{"id":21456897,"url":"https://github.com/gregonnet/ngx-meta-store","last_synced_at":"2025-03-17T03:42:34.931Z","repository":{"id":38481986,"uuid":"276838205","full_name":"GregOnNet/ngx-meta-store","owner":"GregOnNet","description":"lab trying out concepts simplifying state management","archived":false,"fork":false,"pushed_at":"2023-01-06T10:30:38.000Z","size":1518,"stargazers_count":0,"open_issues_count":17,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-23T13:25:05.108Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GregOnNet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-03T07:37:27.000Z","updated_at":"2021-05-31T19:14:16.000Z","dependencies_parsed_at":"2023-02-05T21:32:03.541Z","dependency_job_id":null,"html_url":"https://github.com/GregOnNet/ngx-meta-store","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregOnNet%2Fngx-meta-store","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregOnNet%2Fngx-meta-store/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregOnNet%2Fngx-meta-store/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregOnNet%2Fngx-meta-store/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GregOnNet","download_url":"https://codeload.github.com/GregOnNet/ngx-meta-store/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243971154,"owners_count":20376784,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-23T05:17:04.220Z","updated_at":"2025-03-17T03:42:34.869Z","avatar_url":"https://github.com/GregOnNet.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ngx-meta-store\n\nThis is an attempt to build a feature-driven and very opinionated state management solution.\nIt starts being Angular related since I have most experience with this ecosystem.\nHowever, it might be possible to extract a core that applies to other libraries as well.\n\n## Goals\n\n\u003e Application Developers first\n\nA simple API should be created that delivers a lot of benefits to the developer.\nThings like progress state, network state and url state should be abstracted away.\n\nThe framework should be progressive:\n\n- local state\n  - single object\n  - collection\n- remote state\n  - handle side effects\n- services communicating with each other\n\n## Requirements\n\n- It should handle optimistic/pessimistic updates running a side effect (aka API Call)\n- It should deliver status information about a side effect (loading state, errors)\n- It should handle network connectivity implications\n- It should separate read and write operations\n- It should generate the state management on top of a class representing an entity\n- It should provide a query API loading related entities\n- It should handle language switches\n- It should be possible to filter data on client (with memoization)- \u0026 server-side\n- It should know about loading state of the respective model (isInitialized, isLoading, isLoaded)\n- It should be capable of aggregating all loading states to tell if the app is busy or not\n- It should track errors occurring in side effects\n- It should use immutable operations updating state locally\n- It should allow caching data in-memory\n- It should allow caching/restoring data in/from browser storage\n- It should track changes of an object and persist them (unit of work)\n- It should provide a DebugContext logging all operation opening the gate for developer tools\n- It should allow resetting parts of the state if the user is not authenticated anymore\n\n## Sources\n\n- https://svn.apache.org/repos/asf/zest/site/content/java/2.0/intro.html\n- https://svn.apache.org/repos/asf/zest/site/content/java/2.0/thirty-minutes-intro.html\n- https://restfulapi.net/resource-naming/\n- https://en.wikipedia.org/wiki/Data,_context_and_interaction\n- https://dzone.com/articles/implementing-dci-qi4j\n- https://www.youtube.com/watch?v=U6wFqbkIaQY\n- https://www.youtube.com/watch?v=SxHqhDT9WGI\n\n## API Draft\n\n\u003e None of the information below is final.\n\u003e Currently, I am banging my head around a lot of stuff (see requirements).\n\u003e Help is very appreciated.\n\u003e https://gist.github.com/GregOnNet/54dbc1f781ecdd2e6bae0640889a657b\n\n```ts\nMetaStoreModule.configure({\n  apiEndpoint: '/api',\n  observers: {\n    langauge: LanguageStateObserver,\n    network: NetworkStateObserver,\n    url: UrlStateObserver,\n    auth: AuthenticationObserver;\n  }\n})\n\nexport interface MetaModel\u003cTModel\u003e {\n  modelName: string\n  identifier: keyof TModel;\n}\n\nexport interface MetaModelBehaviourOptions {\n  relaodOnLanguageChange: boolean;          // default true\n  useOptimisticUpdates: boolean;            // default true\n  clearLocalCacheAfterLoggingOut: boolean;  // default true\n}\n\nexport abstract class MetaStore\u003cTModel, TMetaModel extends MetaModel\u003cTModel\u003e\u003e {\n  connect(model: TMetaModel, options: MetaModelBehaviourOptions): Observable\u003cTMetaModel[]\u003e;\n  \n  filter(predicate: MetaPredicate\u003cTMetaModel\u003e): void;\n \n  create(model: TMetaModel): void;\n  update(model: TMetaModel): void;\n  upsert(model: TMetaModel): void;\n  delete(model: TMetaModel): void;\n}\n\nexport class CustomerService extends MetaStore\u003cCustomer\u003e {}\n\nexport interface AuthenticationObserver {\n  authenticationStatusChange: Observable\u003cAuthenticationState\u003e;\n}\n```\n\n### Usage\n\n```ts\n@Injectable({ providedIn: 'root' })\nexport class TaskApi extends MetaApi\u003cTask\u003e{\n  register(): MetaApiRegistration {\n    return {\n      \n    }\n  }\n}\n\nexport class Task {\n  guid: Guid;\n  title: Title;\n  text: Text;\n}\n\nclass Guid implements ValueObject {\n  private _value: string;\n  \n  get value() { return this._value; }\n  \n  private constructor(guid: string) {\n    }\n  \n  create(): Result\u003cGuid\u003e {\n    // validate\n    // set _value\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregonnet%2Fngx-meta-store","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgregonnet%2Fngx-meta-store","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregonnet%2Fngx-meta-store/lists"}