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

gizmo-di

v0.4.0

Published

Gizmo is a lightweight TypeScript DI container for flexible and maintainable dependency management in large applications.

Downloads

29

Readme

Gizmo 🕋

Gizmo is a lightweight dependency injection (DI) container designed to simplify dependency management in your TypeScript projects. It is particularly useful for managing and injecting dependencies in large applications, ensuring that components are easily testable and maintainable.

npm i --save gizmo-di

Features

  • 🏷️ Token-Based Dependency Resolution: Uses tokens to identify and resolve dependencies, providing flexibility and type safety.
  • 📦 Sub-Containers: Allows creation of sub-containers for hierarchical dependency management.
  • 💉 Dependency Injection: Based on active containers.
  • ⚙️ Supports singleton, scoped, and transient modes for controlling dependency lifecycles.
  • 🛡️ Reliability: Type Inference & Checking, Cyclic Dependency Detection and Error Tolerance

Examples

  1. Logger
  2. Inject

API

Gizmo.token<Type>([description[, factory]])

Creates a new Gizmo token.

Parameters:

  • description: string — A string description for the token. (optional, but very recommended)
  • factory: () => Type — A factory function to create the token's default value.

Returns: A GizmoToken<Type> instance.

/** Config token with description & default */
const CONFIG_TOKEN = Gizmo.token(`Config`, () => ({
	debug: false,
	host: '127.0.0.1',
}))

Gizmo.provide<Dep>(dep, ...args)

Provides a dependency using the active Gizmo container.

Parameters

  • dep: Dep — a function or class to be used as the dependency.
  • args: DepTokenArgs<Dep> — the arguments to be passed to the dependency.

Returns: () => DepType<Dep> — a function that provides the dependency.

Throws: Error if the call outside of container.

const LOGGER_TOKEN = Gizmo.token('Logger', Gizmo.provide(
	({ debug }: InferGizmoToken<typeof CONFIG_TOKEN>) => (debug
		? console.info
		: (...args: any[]) => {}
	),
	CONFIG_TOKEN,
))

Gizmo instance methods

set<Type>(token, factory, [options])

Set a factory for a given token and store the factory method and options.

Parameters

  • token: GizmoToken<Type> — the token to associate with the factory.
  • factory: () => Type — the factory function to create the token's value.
  • options: GizmoSetOptions<Type> (optional)
    • mode: singleton | scoped | transient (optional).

Returns: () => Type — function to resolve the token.

// Singleton
container.set(CONFIG_TOKEN, () => ({ debug: true }))

// Transient
container.set(HTTP_CLIENT, () => new HttpClient(), { mode: 'transient' })

has(token)

Check if a token is present in the container.

Parameters

  • token: GizmoToken<any> — the token to check.

Returns: booleantrue if the token is present, otherwise false.

const exists = container.has(CONFIG_TOKEN)

get<Type>(token)

Get the value associated with a token. If not cached, it resolves the value using the factory.

Parameters

  • token: GizmoToken<Type> — the token to get the value for.

Returns: Type | undefined — the resolved value or undefined if not found and no default is provided.

const config = container.get(CONFIG_TOKEN)

resolve<Type>(token)

Get the value associated with a token, throws an error if not found.

Parameters

  • token: GizmoToken<Type> — the token to resolve.

Returns: Type — the resolved value.

Throws: Error if the token cannot be resolved.

const config = container.resolve(CONFIG_TOKEN)

sub()

Creates a sub-container.

Returns: Gizmo instance

const projectGizmo = globalGizmo.sub()

delete<Type>(token)

Remove a token and its value from the container.

Parameters

  • token: GizmoToken — the token to delete.

Returns: void

container.delete(CONFIG_TOKEN)

clear()

Clear all tokens and values from the container.

Returns: void

container.clear()

Types / Utils

GizmoToken

inject(): Type

Injects a dependency based on the active Gizmo container.

Returns: Type — the resolved dependency instance.

const HTTP_CLIENT_TOKEN = Gizmo.token<HttpClient>('HttpClient')
const HTTP_CLIENT_CONFIG_TOKEN = Gizmo.token('HttpClientConfig', () => ({ apiBaseUrl: 'http://127.0.0.1/api/v1' }))

class HttpClient {
	private config = HTTP_CLIENT_CONFIG_TOKEN.inject()
}

container.set(HTTP_CLIENT_TOKEN, () => new HttpClient())

map<TOut>(fn)

Transforms a token into a subordinate token for injectable (Gizmo#provide).

Parameters

  • fn: fn: (value: Type) => TOut — A function that defines the transformation

Returns: GizmoTokenSub<TOut> — Subordinate token type

container.set(LOGGER_TOKEN, Gizmo.provide(
	(debug: boolean) => debug ? console.info : (...args: any[]) => {},
	CONFIG_TOKEN.map(({ debug }) => debug),
))

InferGizmoToken<Token>

Utility type to infer the type from a GizmoToken<Type>.


GizmoTokenMode

Represents token modes.

Values

  • singleton
  • scoped
  • transient
/* eslint no-self-compare:"off" */
const randomValue = () => ({ value: Math.random() })
const RANDOM_TOKEN = Gizmo.token<{ value: number }>('random')

const first = new Gizmo()
const second = first.sub()
const third = second.sub()
const four = four.sub()

// Singleton
first.set(RANDOM_TOKEN, randomValue)
second.set(RANDOM_TOKEN, randomValue)

// Scoped
third.set(RANDOM_TOKEN, randomValue, { mode: 'scoped' })

// Transient
four.set(RANDOM_TOKEN, randomValue, { mode: 'transient' })

// TESTS: Transient
four.resolve(RANDOM_TOKEN).value !== four.resolve(RANDOM_TOKEN).value // "four" not equal "four"

// TESTS: Scoped
third.resolve(RANDOM_TOKEN).value !== four.resolve(RANDOM_TOKEN).value // "third" not equal "four"
third.resolve(RANDOM_TOKEN).value === third.resolve(RANDOM_TOKEN).value // "third" equal "third"

// TESTS: Singleton
second.resolve(RANDOM_TOKEN).value === first.resolve(RANDOM_TOKEN).value // "second" equal "first"
second.resolve(RANDOM_TOKEN).value !== third.resolve(RANDOM_TOKEN).value // "second" not equal "third"

Conclusion

Gizmo provides a structured and efficient way to manage dependencies in your TypeScript projects. By leveraging tokens and different dependency scopes, you can create scalable and maintainable applications. Integrate Gizmo into your project to simplify dependency management and improve code testability.