reactive/data-client
Overview
This skill defines client-side data schemas and patterns for normalizing, denormalizing, and querying JSON returned by APIs. It models Entities, Collections, Unions (polymorphic types), Maps/Values, Queries (memoized selectors), and lifecycle operations like primary key resolution, validation, merge, and invalidation. The goal is predictable async state handling across REST, GraphQL, SSE, and WebSocket feeds. It pairs TypeScript types with runtime schemas to keep UI state normalized and efficient.
How this skill works
You declare schema objects (Entity classes, Collection, Union, Values, All, Query, etc.) that mirror the API payload shape. During normalization the system runs Entity.process → validate → pk → mergeWithStore (calling shouldUpdate/shouldReorder/merge) and stores flattened records. Denormalization reconstructs nested objects via createIfValid → validate → fromJS. Queries run memoized selectors against normalized entries to compute derived results efficiently.
When to use it
- Building a client cache for REST/GraphQL responses that must stay consistent across components
- Handling deeply nested or relational API payloads where normalization improves updates and lookups
- Modeling polymorphic resources (events/messages) that require type discrimination
- Implementing optimistic updates, invalidation, or entity deletion flows
- Writing selectors that depend on normalized store slices for memoized derived data
Best practices
- Define defaults for all non-optional serialized fields on every Entity subclass to avoid undefined state
- Override pk() only when the primary key is not id; return number|string|undefined
- Set static schema on Entities for nested relations and client-side joins instead of manual merging
- Use Entity.process to inject fields derived from request args or URL before validation
- Prefer Denormalize<> types from the library to derive TypeScript types that respect Unions and complex schemas
Example use cases
- Model a Todo app where Todo is an Entity, Todos list is a Collection, and user grouping uses a Query selector
- Normalize a feed of polymorphic events using Union with a shared discriminator field (e.g., type)
- Expose a Values(map) of settings keyed by name and a Collection of items for draggable lists
- Handle SSE/WebSocket messages by normalizing incoming event payloads and merging into the store
- Create a server-paginated resource where All lists every Entity of a kind and Collection handles page inserts
FAQ
Use id by default; override pk() when the API uses another unique field. pk() must return number, string, or undefined for missing keys.
When should I use Union vs nested Entity schema?
Use Union when instances can be different concrete types (polymorphic). Use nested Entity schema when the shape is consistent but related and you want normalized child Entities.
9 skills
This skill helps you design and compose scalable data schemas for entities, collections, and unions, enabling normalized, polymorphic, and relational data in
This skill helps you generate and maintain comprehensive API documentation across core, rest, and graphql packages, improving discoverability and consistency.
This skill configures @data-client/rest for REST APIs, offering a project-specific BaseEndpoint class with urlPrefix, auth, and error handling.
This skill helps you model, fetch, and normalize REST resources with type safety and automatic cache management using @data-client/rest.
This skill assists testing React data-client hooks and components with renderDataHook, fixtures, and nock HTTP mocks for reliable unit and integration tests.
This skill helps you fetch, cache, and stream API data with suspenseful and live updates using Data Client React hooks for React apps.
This skill helps new developers initialize the Reactive Data Client monorepo by installing prerequisites, installing dependencies, building, testing, and
This skill helps you manage global side effects with @data-client Managers, coordinating websockets, SSE, polling, and middleware for a reactive app.
This skill helps you test Vue data-client composables and components with suspense, fixtures, and mocks to ensure reactive state updates.