@e-square/ark
TypeScript icon, indicating that this package has built-in type declarations

16.0.0-next.6 • Public • Published

Ark

An innovative state management library meticulously crafted for Angular.

Installation

Use the package manager npm to install Ark.

npm install @e-square-io/ark@latest

State Management

What is state management? The definition of state management is the handling of the data (state) shared across components in an application.

State management is implemented by stores.

Store

A store is a centralized container where a chunk of the application state resides. Stores can be categorized into two kinds: component stores and global/feature stores. Further discussion will be about feature stores. Feature stores contain data directly related to the application’s or feature's business logic.

Global or feature stores aim to ensure that data can be shared and manipulated across the application predictably and efficiently.

The store in Ark is an injectable Angular service. Extension of the abstract class Ark used to create one. Additionally, the State type and the initial state object must be created. The resulting code will look like the following example.

export interface SessionState {
  user?: User;
}

@Injectable({
  providedIn: 'root',
})
export class SessionStore extends Ark<SessionState> {
  readonly $user = this.select('user');

  constructor() {
    super({}, withStoreConfiguration({ name: 'Session Store' }));
  }
}

Updating the Store

To update the store’s value method update is used. As an argument a partial state object or a callback function that receives the current state and must return a partial state object supposed to be provided.

Besides updating the store’s value, the method update triggers beforeUpdate and afterUpdate interceptors accordingly and the onBeforeUpdate lifecycle hook.

this.sessionStore.update({ user: value });

or

this.sessionStore.update(state => ({ ...state, user: value }))

Getting data from the Store

The store value can be extracted in two ways. First is the instantaneous value that can be achieved with the method getValue. Second, use the method select that returns the computed signal of the store value. Method select can be invoked without arguments, it returns the signal with the whole state object. Or it receives the state object key or projection function that modifies the value of the resulting signal.

$user = this.select('user'); // $user is a readonly signal containing the User object

Customization

Ark constructor receives besides the initial state functional arguments called ArkFeatures. An Ark feature is an object consisting of the feature kind and an object with the feature implementation. Right now, two kinds of features are implemented: interceptors and configuration.

Interceptors

Interceptors are functions being run at specific moments. Right now, there are five types of interceptors are supported:

  1. BeforeInitInterceptor. Runs in the store constructor and can transform the initial value of the store.
  2. AfterInitInterceptor. Runs in the store constructor after the initial state is set.
  3. BeforeUpdateInterceptor. Runs at the beginning of the update method and can transform the state update request.
  4. AfterUpdateInterceptor. Runs at the end of the update process and does additional side actions when the store has been updated.
  5. AfterResetInterceptor. Runs after the store was reset to its initial value.

Interceptors can perform a variety of implicit tasks like validations, logging, adding, or removing data during the store update process.

Write an interceptor

First, decide which moment the interceptor suppose to run. Depending on that, create the function of the appropriate type. Note the types and the number of arguments and return value.

const beforeInit: BeforeInitInterceptor<UpdateSelectState> = initialState => {
  console.log('Before init', initialState);
  initialState.x = '';
  return initialState;
};

const afterInit: AfterInitInterceptor<UpdateSelectState> = initialState => console.log('After init', initialState);

const beforeUpdate: BeforeUpdateInterceptor<UpdateSelectState> = (currState, newState, store) => {
  console.log('%cBefore Update #1.', 'color: lightgreen');
  console.log('Curr state:', currState, 'new state:', newState, 'store', store);
  return newState;
};

const afterUpdate: AfterUpdateInterceptor<UpdateSelectState> = state => console.log('Updated successfully', state);

Now, provide all your interceptor functions to the ArkInterceptors object and supply it with the withInterceptors function to super in the store constructor. Multiple interceptors can intercept the same moment and multiple withInterceptors functions can be used.

Add and remove interceptor at run-time

Every store has the property hooks that contains the instance of the Hooks class. The Hooks class provides methods to add and remove interceptors at run-time.

Store Lifecycle

Ark introduces its lifecycle additionally to the standard Angular. Your application can use lifecycle hooks methods, similar to component lifecycle hooks, to tap into the store update events.

Responding to Store update events

Respond to update events in the lifecycle of the store by implementing one or more of the lifecycle hook interfaces. The hooks allow you to act on the store and the store value at the appropriate moment when the update occurs. Each interface defines the prototype for a single hook method, whose name is the interface name. For example, the OnBeforeUpdate interface has a hook method onBeforeUpdate. If you implement this method in your store class, Ark calls it shortly after the update process will be initiated.

onBeforeUpdate(currentState: UpdateSelectState, newState: Partial<UpdateSelectState>): Partial<UpdateSelectState> {
  console.log('onBeforeUpdate', 'curr', currentState, 'new', newState);

  return newState;
}

onAfterUpdate(): void {
  console.log('onAfterUpdate', this.getValue());
}

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Support

If you encounter any problems or have any questions, please file an issue on our GitHub page.

Package Sidebar

Install

npm i @e-square/ark

Weekly Downloads

36

Version

16.0.0-next.6

License

MIT

Unpacked Size

182 kB

Total Files

69

Last publish

Collaborators

  • groupp
  • ronnetzer
  • eliraneliassy