Skip to content

[pull] master from reactive:master#97

Merged
pull[bot] merged 2 commits intoerickirt:masterfrom
reactive:master
Mar 29, 2026
Merged

[pull] master from reactive:master#97
pull[bot] merged 2 commits intoerickirt:masterfrom
reactive:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull bot commented Mar 29, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

ntucker and others added 2 commits March 29, 2026 14:52
Allow per-Entity configuration of the denormalization depth limit via
`static maxEntityDepth`. This lets users lower the limit (default 128)
on entities that participate in deep bidirectional relationships,
without requiring any provider or controller configuration.

The depth check in `getUnvisit()` now reads `schema.maxEntityDepth`
with a fallback to the existing 128 default.

Made-with: Cursor
* feat: add Lazy schema class for deferred relationship denormalization

Introduces schema.Lazy(innerSchema) that:
- normalize: delegates to inner schema (entities stored normally)
- denormalize: no-op (returns raw PKs unchanged)
- .query getter: returns LazyQuery for use with useQuery()

LazyQuery resolves entities lazily:
- queryKey: delegates to inner schema if it has queryKey, otherwise passes through args[0]
- denormalize: delegates to inner schema via unvisit (full entity resolution)

No changes needed to EntityMixin or unvisit - Lazy.denormalize as no-op
means the existing denormalize loop works without any special handling.

Co-authored-by: natmaster <natmaster@gmail.com>

* test: add comprehensive tests for Lazy schema

Tests cover:
- Normalization: inner entities stored correctly through Lazy wrapper
- Denormalization: Lazy field leaves raw PKs unchanged (no-op)
- LazyQuery (.query): resolves array of IDs, delegates to Entity.queryKey,
  handles missing entities, returns empty for empty IDs
- Memoization isolation: parent denorm stable when lazy entity changes
- Stack safety: 1500-node bidirectional graph does not overflow

Co-authored-by: natmaster <natmaster@gmail.com>

* docs: add API documentation for Lazy schema

Documents the Lazy schema class including:
- Constructor and usage patterns (array, entity, collection)
- .query accessor for useQuery integration
- How normalization/denormalization works
- Performance characteristics

Co-authored-by: natmaster <natmaster@gmail.com>

* test: rewrite Lazy tests with full scenario coverage

Replaced shallow tests with thorough scenario-based tests (27 total):

- Round-trip: normalize API data → denormalize parent (Lazy stays raw) →
  LazyQuery resolves to full entities with all fields checked
- Mixed schema: non-Lazy Manager resolves alongside Lazy buildings on
  same entity; verified instanceof, field values, paths
- Dependency tracking: parent paths include Manager but exclude Building;
  LazyQuery paths include Building PKs but exclude Department
- LazyQuery edge cases: subset IDs, empty array, missing entity IDs
  filtered out, single Entity delegation via Building.queryKey
- Memoization isolation: parent ref equality preserved when Building
  changes; LazyQuery result updates when entity changes; ref equality
  maintained on unchanged state
- Nested Lazy: resolved Building still has its own Lazy rooms as raw IDs;
  second-level LazyQuery resolves Room entities
- Bidirectional Lazy: 1500-node chain no overflow; step-through resolution
  verifying each level's Lazy field stays raw while resolved entity is correct
- Lazy.queryKey returns undefined (not queryable directly)

Co-authored-by: natmaster <natmaster@gmail.com>

* fix: lint errors and add changeset for Lazy schema

- Prefix unused params with _ to satisfy @typescript-eslint/no-unused-vars
- Fix prettier formatting (auto-fixed via eslint --fix)
- Fix import order in schema.d.ts
- Remove unused imports in test file
- Add changeset for @data-client/endpoint, rest, graphql (minor)

Co-authored-by: natmaster <natmaster@gmail.com>

* fix: LazyQuery.queryKey skips delegation for non-keyed schemas (Array, Values)

When the inner schema is an explicit class instance (e.g. new schema.Array(Building)),
LazyQuery.queryKey would delegate to the inner schema's queryKey which always returns
undefined for Array and Values schemas. This caused MemoCache.query to short-circuit
and return no data, because the args[0] fallback was never reached.

Fix: only delegate to inner schema's queryKey when schema.key exists (Entity, Collection),
which distinguishes schemas with meaningful queryKey logic from container schemas
(Array, Values) that have no-op stubs.

Also fixes pre-existing TypeScript errors in Lazy.test.ts and adds tests for explicit
schema.Array and schema.Values inner schemas.

Co-authored-by: Nathaniel Tucker <me@ntucker.me>

* internal: lint

* enhance: Stricter args typing

* docs: Docs updates

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@pull pull bot locked and limited conversation to collaborators Mar 29, 2026
@pull pull bot added the ⤵️ pull label Mar 29, 2026
@pull pull bot merged commit 63633c7 into erickirt:master Mar 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant