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

reprovider

v1.1.0-stable

Published

A minimalist package created created for manage services using depedency injection easly and quickly.

Downloads

23

Readme

Texto alternativo

Reprovider

A minimalist package created created for manage services using depedency injection easly and quickly.

Overview

When our react app is scaling sometimes is necessary that we organize the logic for get a better understanding of our code.

Reprovider is designed for developers that want get a quickly and organized service provider in a react application using techniques like the Dependency Injection very simple.

With reprovider we can create services and consume into a component or outside of it.

Reprovider supports Redux for inject services into reducers and thunks. If you want use reprovider with redux, Read this section

Full docs

Read the latest full docs here

How it works

Texto alternativo

Quick start

Install

with npm:

    npm i reprovider

Using Reprovider

First create the repository, it can contains the interacions with an A.P.I or Database.

greets.repository.ts

export class GreetsRepository {
  hello = () => "Hello ";
  goodBay = () => "Goodbay ";
}

Now create the service and inject the repository into constructor.

greets.service.ts

import { GreetsRepository } from "../repository/greets.repository";

export class GreetsService {
  constructor(private readonly repository: GreetsRepository) {}
  sayHello = (): string => `${this.repository.hello()} World From Reprovider`;
  sayGoodbye = (): string =>
    `${this.repository.goodBay()} World From Reprovider`;
}

Its time to create the registry file.

It contains all services with its dependencies that will register into ServiceProvider

registry.ts

import { Service } from "reprovider";
import { GreetsService } from "./services/greets.service";
import { GreetsRepository } from "./repository/greets.repository";

export const services: Service[] = [
  {
    description: "Service for greeting people",
    service: GreetsService,
    dependencies: [GreetsRepository],
  },
];

Once do you configure the services and declared into registry file. FInally we can inject the services into the app.

For that, add the ServiceProvider at the top of the app.

The service provided will be responsible of create the context that we will using later calling the useProvider hook.

app.tsx

import { ServiceProvider } from "reprovider";
import SayHello from "./components/say-hello.component";
import { services } from "./core/registry";

const App = (): JSX.Element => {
  return (
    <ServiceProvider services={services}>
      <SayHello />
    </ServiceProvider>
  );
};

export default App;

Say hello with useProvider

Finally, just import the useProvider, pass the reference of Service that you wan use and desestructure the provider.

Optional: You can rename the provider as you want. This is recommended for understand the code, better.

say-hello.component.tsx

import { useProvider } from "reprovider";
import { GreetsService } from "../core/services/greets.service";

/**
 * Show a simple hello world
 *
 */
const SayHello = () => {
  /**
   * Optional: Also we can rename the provider or use the standard reference.
   * Is recommended rename the provider for understand the code better
   */
  const { provider: greetsService } = useProvider(GreetsService);

  return (
    <div>
      <h1>{greetsService.sayHello()}</h1>
    </div>
  );
};

export default SayHello;

Buildux

What is buildux?

Buildux is a slice builder that allows inject services into reducers and thunks creating a context and consume services from reducers easy. It works with redux-toolkit library.

How Buildux Works

You can review the next graph for understand the buildux flow

Texto alternativo

Usage

Install the dependencies

npm install reprovider @reduxjs/toolkit react-redux

First create the state interface

counter-state.interface.ts

export interface CounterState {
  value: number;
}

Now, create the buildux file, import the state, and pass the state type to the instance. This will return a context that you will use later in reducers.

counter.buildux.ts

import { Buildux } from "reprovider";
import { CounterState } from "../../interfaces/counter-state.interface";

const { context } = new Buildux<CounterState>({
  name: "counter",
  initialState: { value: 0 },
});

After created the Buildux instance, we need create the reducers. For that, use the createReducers method:

counter.buildux.ts

const { context } = new Buildux<CounterState>({
  name: "counter",
  initialState: { value: 0 },
}).createReducers({
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
  },
});

then exports the actions created from reducers and the reducer from context:

counter.buildux.ts

export const { increment, decrement } = context.actions;
export const counterReducer = context.reducer;

Now create the store and import the exported reducer from counter.buildux.ts

store.ts

import { configureStore } from "@reduxjs/toolkit";
import { counterReducer } from "./counter-store/counter.buildux";

export const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

In your index.tsx, import the store and the Provider Component and pass the store to tag.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";

import { store } from "./core/store/store";
import { Provider } from "react-redux";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

For consume the reducers and dispatch actions we need create these hooks:

hooks.ts

import { useDispatch, useSelector } from "react-redux";
import type { TypedUseSelectorHook } from "react-redux";
import { AppDispatch, RootState } from "../store/store";

//Hooks for read and emit states with redux.

//Calls an action
export const useAppDispatch: () => AppDispatch = useDispatch;

//Read the state
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

Now, we are ready to use the states and actions. For that, import the hooks in the component and use the hooks as follows:

app.tsx

const count = useAppSelector((state) => state.counter.value);
const dispatch = useAppDispatch();

app.tsx

import reproviderLogo from "./assets/reprovider_logo.png";
import "./App.css";
import { useAppSelector, useAppDispatch } from "./core/hooks/hooks";
import {
  decrement,
  increment,
} from "./core/store/counter-store/counter.buildux";

function App() {
  const count = useAppSelector((state) => state.counter.value);
  const dispatch = useAppDispatch();
  return (
    <>
      <div>
        <img src={reproviderLogo} className="logo" alt="Reprovider logo" />
        <a href="https://redux-toolkit.js.org/">
          <img
            src="https://redux-toolkit.js.org/img/redux.svg"
            className="logo Redux Toolkit"
            alt="Redux toolkit logo"
          />
        </a>
      </div>
      <h1>Reprovider + Redux Example</h1>
      <div className="card">
        <button onClick={() => dispatch(increment(1))}>+1</button>
        <h1>Counter value is: {count}</h1>
        <button onClick={() => dispatch(decrement(1))}>-1</button>
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
    </>
  );
}

export default App;

You can read the complete example reading here

Buildux Thunk

Overview

Buildux provide a custom thunk for asincronus calls and it's an implementation of createAsyncThunk.

Creating a BuilduxThunk

import { builduxThunk } from "reprovider";

builduxThunk<User[], ActionArgument>({
  // You can infer the type of the 'action' parameter here if it has one.
  description: "Get user from API",
  reference: "/users",
  action: async () => {
    const usersService = context.consumer.get(UsersService);
    const users = await usersService.getUsers();
    return users;
  },
});

For use the thunk we need register into thunkRegistry method that it's provided when we create the Buildux instance

users.buildux.ts

const { context, thunksRegistry, createReducers } = new Buildux<
  UsersState,
  UsersThunks
>({
  name: "users",
  services,
  initialState: {
    users: [],
  },
});

createReducers(usersReducers);

thunksRegistry(context, (context) => ({
  fetchUsers: builduxThunk<User[]>({
    description: "Get user from API",
    reference: "/users",
    action: async () => {
      const usersService = context.consumer.get(UsersService);
      const users = await usersService.getUsers();
      return users;
    },
  }),
}));

also we can declare our thunks out of our buildux file and the pass the reference into thunksRegistry.

users-thunks.registry.ts

export const userThunksRegistry = <T>(context: BuilduxContext<T>) => ({
  fetchUsers: builduxThunk<User[]>({
    description: "Get user from API",
    reference: "/users",
    action: async () => {
      const usersService = context.consumer.get(UsersService);
      const users = await usersService.getUsers();
      return users;
    },
  }),
});

then we can import it into buildux file.

users.buildux.ts

const { context, thunksRegistry } = new Buildux<UsersState>({
  name: "users",
  services,
  initialState: {
    users: [],
  },
});
createReducers(usersReducers);

//Imported here
thunksRegistry(context, userThunksRegistry);

Buildux Examples

You can view the examples with buildux and thunks here

Injecting Services and consuming into reducer

If you need consume services into a reducer you can follow the next steps:

Create the registry file for store the services for slice

Recomendation:

It is recommended to create a registry for the slice and only insert the services that are part of it. This helps build a better code structure.

Create the registry file

registry.ts

import { Service } from "reprovider";

export const services: Service[] = [
  {
    description: "Service for greeting people",
    service: UsersService,
    dependencies: [UsersRepository],
  },
];

users.buildux.ts

import { services } from "./registry";

const { context } = new Buildux<UsersState>({
  name: "users",
  services,
  initialState: {
    name: "",
    lastName: "",
    email: "",
  },
}).createReducers({
  getUsers: (state) => {
    const service = context.consumer.get(MyService);
    // Do something with your service...
  },
});

Consuming services into a thunk

export const userThunksRegistry = <T>(context: BuilduxContext<T>) => ({
  fetchUsers: builduxThunk<User[]>({
    description: "Get user from API",
    reference: "/users",
    action: async () => {
      //Read the service from context.
      const usersService = context.consumer.get(UsersService);
      const users = await usersService.getUsers();
      return users;
    },
  }),
});

Examples

You can view more examples follow this link