GregOnNet / ngx-meta-store

lab trying out concepts simplifying state management

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ngx-meta-store

This is an attempt to build a feature-driven and very opinionated state management solution. It starts being Angular related since I have most experience with this ecosystem. However, it might be possible to extract a core that applies to other libraries as well.

Goals

Application Developers first

A simple API should be created that delivers a lot of benefits to the developer. Things like progress state, network state and url state should be abstracted away.

The framework should be progressive:

  • local state
    • single object
    • collection
  • remote state
    • handle side effects
  • services communicating with each other

Requirements

  • It should handle optimistic/pessimistic updates running a side effect (aka API Call)
  • It should deliver status information about a side effect (loading state, errors)
  • It should handle network connectivity implications
  • It should separate read and write operations
  • It should generate the state management on top of a class representing an entity
  • It should provide a query API loading related entities
  • It should handle language switches
  • It should be possible to filter data on client (with memoization)- & server-side
  • It should know about loading state of the respective model (isInitialized, isLoading, isLoaded)
  • It should be capable of aggregating all loading states to tell if the app is busy or not
  • It should track errors occurring in side effects
  • It should use immutable operations updating state locally
  • It should allow caching data in-memory
  • It should allow caching/restoring data in/from browser storage
  • It should track changes of an object and persist them (unit of work)
  • It should provide a DebugContext logging all operation opening the gate for developer tools
  • It should allow resetting parts of the state if the user is not authenticated anymore

Sources

API Draft

None of the information below is final. Currently, I am banging my head around a lot of stuff (see requirements). Help is very appreciated. https://gist.github.com/GregOnNet/54dbc1f781ecdd2e6bae0640889a657b

MetaStoreModule.configure({
  apiEndpoint: '/api',
  observers: {
    langauge: LanguageStateObserver,
    network: NetworkStateObserver,
    url: UrlStateObserver,
    auth: AuthenticationObserver;
  }
})

export interface MetaModel<TModel> {
  modelName: string
  identifier: keyof TModel;
}

export interface MetaModelBehaviourOptions {
  relaodOnLanguageChange: boolean;          // default true
  useOptimisticUpdates: boolean;            // default true
  clearLocalCacheAfterLoggingOut: boolean;  // default true
}

export abstract class MetaStore<TModel, TMetaModel extends MetaModel<TModel>> {
  connect(model: TMetaModel, options: MetaModelBehaviourOptions): Observable<TMetaModel[]>;
  
  filter(predicate: MetaPredicate<TMetaModel>): void;
 
  create(model: TMetaModel): void;
  update(model: TMetaModel): void;
  upsert(model: TMetaModel): void;
  delete(model: TMetaModel): void;
}

export class CustomerService extends MetaStore<Customer> {}

export interface AuthenticationObserver {
  authenticationStatusChange: Observable<AuthenticationState>;
}

Usage

@Injectable({ providedIn: 'root' })
export class TaskApi extends MetaApi<Task>{
  register(): MetaApiRegistration {
    return {
      
    }
  }
}

export class Task {
  guid: Guid;
  title: Title;
  text: Text;
}

class Guid implements ValueObject {
  private _value: string;
  
  get value() { return this._value; }
  
  private constructor(guid: string) {
    }
  
  create(): Result<Guid> {
    // validate
    // set _value
  }
}

About

lab trying out concepts simplifying state management


Languages

Language:TypeScript 86.4%Language:JavaScript 10.0%Language:HTML 3.2%Language:Sass 0.4%