https://github.com/gregonnet/ngx-meta-store
lab trying out concepts simplifying state management
https://github.com/gregonnet/ngx-meta-store
Last synced: about 1 year ago
JSON representation
lab trying out concepts simplifying state management
- Host: GitHub
- URL: https://github.com/gregonnet/ngx-meta-store
- Owner: GregOnNet
- Created: 2020-07-03T07:37:27.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T10:30:38.000Z (over 3 years ago)
- Last Synced: 2025-01-23T13:25:05.108Z (over 1 year ago)
- Language: TypeScript
- Size: 1.45 MB
- Stars: 0
- Watchers: 3
- Forks: 1
- Open Issues: 17
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 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
- https://svn.apache.org/repos/asf/zest/site/content/java/2.0/intro.html
- https://svn.apache.org/repos/asf/zest/site/content/java/2.0/thirty-minutes-intro.html
- https://restfulapi.net/resource-naming/
- https://en.wikipedia.org/wiki/Data,_context_and_interaction
- https://dzone.com/articles/implementing-dci-qi4j
- https://www.youtube.com/watch?v=U6wFqbkIaQY
- https://www.youtube.com/watch?v=SxHqhDT9WGI
## 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
```ts
MetaStoreModule.configure({
apiEndpoint: '/api',
observers: {
langauge: LanguageStateObserver,
network: NetworkStateObserver,
url: UrlStateObserver,
auth: AuthenticationObserver;
}
})
export interface MetaModel {
modelName: string
identifier: keyof TModel;
}
export interface MetaModelBehaviourOptions {
relaodOnLanguageChange: boolean; // default true
useOptimisticUpdates: boolean; // default true
clearLocalCacheAfterLoggingOut: boolean; // default true
}
export abstract class MetaStore> {
connect(model: TMetaModel, options: MetaModelBehaviourOptions): Observable;
filter(predicate: MetaPredicate): void;
create(model: TMetaModel): void;
update(model: TMetaModel): void;
upsert(model: TMetaModel): void;
delete(model: TMetaModel): void;
}
export class CustomerService extends MetaStore {}
export interface AuthenticationObserver {
authenticationStatusChange: Observable;
}
```
### Usage
```ts
@Injectable({ providedIn: 'root' })
export class TaskApi extends MetaApi{
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 {
// validate
// set _value
}
}
```