Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
@s-libs/app-state
Advanced tools
Changelog
16.0.0-next.2 (2023-05-09)
AngularContext
no longer automatically provides HttpClient
. This is a good thing, because it will now catch when you forget to import/provide it in your production code. But it's technically a breaking change because any tests that relied on it will start to fail.Readme
An observable state management library. Think of it like Redux, but without actions or reducers. That makes it a natural fit for anyone who wants the benefits of centralized state management, without adopting a function style of programming.
Once you are familiar with the basics, it may help to see the api documentation.
A basic idea behind this library is to keep all the state of your app in one place, accessible for any component or service to access, modify and subscribe to changes. This has several benefits:
2 terms are worth defining immediately. As they are used in this library, they mean:
Install along with its peer dependencies using:
npm install @s-libs/app-state @s-libs/ng-core @s-libs/rxjs-core @s-libs/js-core @s-libs/micro-dash
Define the shape of your application state using typescript classes or interfaces (but prefer classes, as noted in the style guide below). For example:
// state/my-state.ts
import { User } from "./user";
export class MyState {
loading = true;
currentUser?: User;
}
// state/user.ts
export class User {
id: string;
name: string;
}
Then create a subclass of RootStore
. A single instance of that class will serve as the entry point to obtain and modify the state it holds. Most often you will make that class an Angular service that can be injected anywhere in your app. For example:
// state/my-store.service.ts
import { Injectable } from "@angular/core";
import { RootStore } from "@s-libs/app-state";
import { MyState } from "./my-state";
@Injectable({ providedIn: "root" })
export class MyStore extends RootStore<MyState> {
constructor() {
super(new MyState());
}
}
Consider this translation of the counter example from the ngrx/store
readme:
// app-state.ts
export class AppState {
counter = 0;
}
// app-store.ts
@Injectable({ providedIn: "root" })
export class AppStore extends RootStore<AppState> {
constructor() {
super(new AppState());
}
}
// my-app-component.ts
@Component({
selector: "my-app",
template: `
<button (click)="increment()">Increment</button>
<div>Current Count: {{ counterStore.$ | async }}</div>
<button (click)="decrement()">Decrement</button>
<button (click)="reset()">Reset Counter</button>
`,
})
export class MyAppComponent {
counterStore: Store<number>;
constructor(store: AppStore) {
this.counterStore = store("counter");
}
increment() {
this.counterStore.set(this.counterStore.state() + 1);
}
decrement() {
this.counterStore.set(this.counterStore.state() - 1);
}
reset() {
this.counterStore.set(0);
}
}
new StateObject()
come with the default values for all its properties.set()
and the other mutation methods on store objects freely (because mutating causes that object and all its ancestors to be recreated as plain objects or arrays, losing any methods defined by its prototype).state()
early. E.g.:
store.state().currentUser.name; // do this
store("currentUser")("name").state(); // not this
This allows the use of !
to easily declare the presence of an intermediate object. E.g.:
store.state().currentUser!.name; // do this
store<"currentUser", User>("currentUser")("name").state(); // not this
This package includes an abstract class, UndoManager
, to assist you in creating undo/redo functionality. For example, a simple subclass that captures every state change into the undo history:
@Injectable()
class UndoService extends UndoManager<MyAppState, MyAppState> {
private skipNextChange = true;
constructor(store: MyAppStore) {
super(store);
store.$.subscribe(() => {
if (this.skipNextChange) {
this.skipNextChange = false;
} else {
this.pushCurrentState();
}
});
}
protected extractUndoState(state: MyAppState) {
return state;
}
protected applyUndoState(stateToApply: MyAppState) {
this.skipNextChange = true;
this.store.set(stateToApply);
}
}
You will likely want to be more selective about which states are pushed into the undo history, rather than subscribing to all changes. Real-world usage will be more selective about calling pushCurrentState()
, and maybe from other places in your app instead of within the service itself.
You may also want to tailor which pieces of state are included in undo/redo operations by returning only those portions from extractUndoState()
(which will change what is passed to applyUndoState()
).
Consult the documentation in the source of UndoState
for more options and information.
FAQs
An observable state management library. Directly read, write, and observe any part of your state without writing any selectors, actions, or reducers.
The npm package @s-libs/app-state receives a total of 480 weekly downloads. As such, @s-libs/app-state popularity was classified as not popular.
We found that @s-libs/app-state demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.