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

gentleman-state-manager

v1.1.0

Published

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.0.5.

Downloads

4

Readme

Gentleman State Manager

This library was generated with Angular CLI version 10.0.5.

Description

Hi everyone ! this is a super easy and comfortable way of using reactive programming to manage the state of your application. This library is based on Rxjs Behaviour Subject observables to manage the different states of your application using the concept of a single source of truth.

First...Let's learn some things !

Reactive programming is the concept of developing code where different entities are watching trough an information channel for data to pass, and when it does, each entity will "react" to that situation doing their business logic.

Imagine an empty tube with 3 holes in it, at each hole we have a person looking trough it and waiting for a little ball to pass. Because each person is different, they will see different aspects of the ball. For example, one can see that the ball is red, another that the ball is bouncing a little when it's passing trough ...or even that maybe it's not a ball at all !.

That's exactly what reactive programming is ! we have an information channel (observables) containing the data that is passing trough it, and on the other hand we have entities (the angular components for example) that will be subscribed and waiting for that information to pass ...and when it does, they will react to it doing what ever business logic we coded for them.

Redux, Ngrx/store, etc. are libraries that provide tools to manage the state of the application using the concept of "A Single Source Of Truth", these means that the whole information of the app will be contained inside a "store", a place where you can access useful and up to date information. Each time a change happens
inside your application, information wise, the store will be updated with the latest changes. So you don't need to call the back end again for an update if not needed and also all entities that are watching the store's states will be automatically alerted of the change.

Rxjs is a library containing a lot of amazing tools to manage these information channels, these provide the ability to combine and modify observables with the inclusion of new kinds of observables to use, each one with their own functionalities.

We are going to use Behaviour Subjects a lot in this case, it's an observable that will always contain the last data that passed trough it....which is amazing for what we want to do ! When ever we send information trough the Behaviour Subject, even if an entity subscribes AFTER the information has been sent, it will receive the latest data ! so we don't loose anything.

The main concept of Gentleman State Manager, is providing an useful way to manage the state of your application, using understandable and cristal clear tools like Rxjs to do so. In short, we create an array of observables identified by their key, that can be increased in size by each module (so yes, we use lazy loading !) to manage the information that passes trough the different entities of your Angular application.

How to use

1- Create an object using the SourceOfTruthInitiate class provided by the library. I recommend having a state.ts per module, representing the state interfaces and properties :

state.ts for Root ( AppModule ):

export interface FirstState {
   stateProperty: string | null;
}

export enum FirstStateProperties {
   STATEPROPERTY: 'stateProperty'
}

export enum StoreKeys {
   FIRSTSTATE: 'firstState'
}

AppModule:

const sourceOfTruthInitiate: SourceOfTruthInitiate[] = [
    {
        key: StoreKeys.FIRSTSTATE,
        state: {
            stateProperty: 'your state property value'
        },
        stateProperties: FirstStateProperties
    }
];
  • key: represents the key to access the proper observable that we want to use.
  • state: the empty state of the object that will pass trough the observable.
  • stateProperties: the properties of the object, we are going to use it to access the information without ambiguities.

2- import GentlemanStateManagerModule inside your application in the following way:

@NgModule({
    imports: [
        ...
        GentlemanStateManagerModule.forRoot(sourceOfTruthInitiate)
        ...
    ]
})
export class AppModule {}

3- use our apis to access the information or send something new !

Example:

export class OverviewMetricComponent implements OnDestroy {
     constructor(gentlemanStateManager: GentlemanStateService) {
        console.log(gentlemanStateManager.getEntity(StoreKeys.FIRSTSTATE).getPropertyFromState(FirstStateProperties.STATEPROPERTY));
    }
}

4- to lazy load more observables just do the same functionality as in the app module, but in the constructor of your lazy loaded one.

Example:

state.ts for Root ( AppModule ):

...
export enum StoreKeys {
   FIRSTSTATE: 'firstState',
   LAZYLOADEDSTATE: 'lazyLoadedState' // we add the new state key
}
...

state.ts of your lazy loaded module:

export interface LazyLoadedState {
   lazyLoadedStateProperty: string | null;
}

export enum LazyLoadedStateProperties {
   LAZYLOADEDSTATEPROPERTY: 'lazyLoadedStateProperty'
}

const sourceOfTruthInitiate: SourceOfTruthInitiate[] = [
    {
        key: StoreKeys.LAZYLOADEDSTATE,
        state: {
            lazyLoadedStateProperty: 'Your Lazy Loaded State Property'
        },
        stateProperties: LazyLoadedStateProperties
    }
];

@NgModule({
   ...
})
export class LazyLoadedModule {
   constructor(gentlemanStateService: GentlemanStateService) {
    sourceOfTruthInitiate.forEach(state => gentlemanStateService.createObservable(state.key, state.state, state.stateProperties));
  }
}

Api

Array Of Observables Management :

createObservable

/**
* @desc it creates and observable and adds it to the observable array.
* @param key: the key to be used to represent the observable item inside the array
* @param state: the state of the observable, the object that represents what the observable is going to contain
* @return void
*/
  createObservable(key: string, state: any, stateProperties: StateProperties): void

getEntity

/**
* @desc it returns the selected observable using the provided key.
* @param key - the key to be used to represent the observable item inside the array
* @return GentlemanStateObject
*/
  getEntity(key: string): GentlemanStateObject

destroyObservable

/**
* @desc it destroys an object from the observable array.
* @param key - the key to be used to represent the observable item inside the array
* @return void
*/
  destroyObservable(key: string): void

GentlemanStateObject :

getObservable

/**
* @desc returns the observable that contains the state for async operations - it listens for changes
* @return Observable
*/
  getObservable(): Observable

getStateProperties

/**
* @desc returns the state properties object
* @return StateProperties
*/
  getStateProperties(): StateProperties

unsubscribe (use it when you are destroying the main component of your module)

/**
* @desc unsubscribes from the observable
* @return void
*/
  unsubscribe(): void

getStateSnapshot

/**
* @desc returns the value of the state at the time of the call
* @return any
*/
  getStateSnapshot(): any

getPropertyFromState

/**
* @desc returns the value of a property of the state at the time of the call
* @param property - the name of the requested property
* @return any
*/
  getPropertyFromState(property: string): any

getPropertyFromState

/**
* @desc returns the value of a property of the state at the time of the call
* @param property - the name of the requested property
* @return any
*/
  getPropertyFromState(property: string): any

getPropertyFromObservable

/**
* @desc returns the value of a property of the state for async operations - it listens for changes
* @param property - the name of the requested property
* @return Observable
*/
  getPropertyFromObservable(property: string): Observable<any>

setObservableValues

/**
* @desc sets the value for a certain property inside the state, triggers an async event
* @param value - the value for the requested property
* @param property - the name of the requested property
* @param emit - if true it will trigger an async event
* @return void
*/
  setObservableValues(value: any, property: string | null = null, emit = true): void

setStateValues

/**
* @desc sets the value for a certain property inside the state, doesn't triggers an async event
* @param value - the value for the requested property
* @param property - the name of the requested property, if no property it will try to patch the values into the state
* @return void
*/
  setStateValues(value: any, property: string | null): void

resetState

/**
* @desc resets the state
* @return void
*/
  resetState(): void