fix: materialize placeholder-backed hasOne creating relations on persist#23
Merged
fix: materialize placeholder-backed hasOne creating relations on persist#23
Conversation
Without materialization, extractNestedResultsFromNode sees a relation with currentId = null and skips it, so the server-assigned ID is never mapped back — the relation stays in 'creating' with empty placeholderData and HasOneHandle keeps returning a blank PlaceholderHandle until refresh. Move materialization into a dedicated pass (materializePlaceholderRelations) called at the top of collectUpdateData, and extend the existing materializeEntityRelations used by collectCreateData. The collection phase is back to a pure read over the store, and both create and update flows go through the shared materialization + standard tempId inline-create path so post-persist ID mapping works uniformly.
Rename materializeEntityRelations/materializePlaceholderRelations to materializeForCreate/materializeForUpdate so call sites express when they run, not what they walk. Replace the silent fallback in collectHasOneOperation 'creating' branch with an invariant throw for non-empty placeholderData — reaching it means materialization was skipped, which would regenerate the pre-fix ghost-create payload the whole PR is meant to prevent. Empty placeholderData remains a legitimate no-op. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- nested placeholder hasOne (creating → creating) recursively materializes - placeholder hasOne carried on a hasMany-created item - invariant throw when a broken MutationSchemaProvider bypasses materialization with a non-empty placeholderData Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a persist bug where a hasOne relation in
creatingstate backed byPlaceholderHandledata (typical admin create form) was never materialized into a real store entity. As a resultextractNestedResultsFromNodesawcurrentId = nulland skipped ID mapping — the server persisted the child correctly, but the client store stayed withstate: 'creating'and emptyplaceholderData, soHasOneHandlekept returning a blankPlaceholderHandleuntil refresh.materializePlaceholderRelations) called at the top ofcollectUpdateData, and folded into the existingmaterializeEntityRelationson the create path.collectUpdateOneRelationhad a hiddencreateEntity+setRelationside-effect mid-collection).tempIdinline-create path, so post-persist ID mapping works uniformly.Test plan
tests/hasOneCreatingMaterialization.test.ts:creatinghasOne gets materialized on both create and update of parentplaceholderDatadoes not mutate the storeBatchPersister: after persist the relation isconnectedto a server-persisted User with mapped ID and cleared placeholdertests/mutationCollector.test.tspasses (one assertion loosened to not depend on operation ordering)bun testgreen