feat(query): type-referenced invalidation — .exact(TodoList()) over raw keys#156
Merged
Conversation
…aw keys Invalidation was only .prefix/.exact/.tag over raw QueryKeys, so inside one mutation the same query was referenced type-safely in optimistic (.update(TodoList())) and stringly one line later (.exact(["todos"])) — restating a key that @query(prefix:) already owns. A renamed prefix silently breaks the invalidation while the compiler stays quiet. Add @mainactor static overloads of the case names taking the typed owner of the key — exact<Q: Query>(_:) and prefix<Q: Query>(_:) — resolving eagerly to the existing cases. No new vocabulary: the same words now accept the query type, so invalidations rhymes with optimistic. Raw-key spellings remain for keys no Query type owns. Tests pin that the typed spellings produce values IDENTICAL to the raw-key ones (the dispatch machinery behind the cases is provably shared) and that array literals keep resolving to the cases (no overload capture). Dogfood: all 4 stringly sites in the repo converted — TodoCRUD x3 (.exact(TodoList())) and QueryDemo's parameterized .exact(UserByID(id: id)); EmbeddedTemplates.swift regenerated (both are embedded templates). Verified: host 1379/277, TodoCRUD + QueryDemo wasm builds clean, TodoCRUD Playwright e2e 5/5 against the real Bun backend scaffolded from the new templates (optimistic-add-reconcile + rollback exercise the changed path). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📦 Bundle size
✅ Within budget (≤5% growth allowed). Baseline: Swift 6.3, WASM SDK 6.3-RELEASE, measured 2026-06-18. |
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.
Part II Wave 1 · #3 — invalidation restates keys the query type already owns
Invalidationwas only.prefix(QueryKey)/.exact(QueryKey)/.tag(QueryTag)over raw keys. Inside one mutation the same query gets referenced type-safely inoptimisticand stringly one line later:A renamed prefix silently breaks the invalidation; the compiler stays quiet.
Change
@MainActorstatic overloads of the case names taking the typed owner of the key, resolving eagerly to the existing cases:invalidationsrhymes withoptimistic:[.exact(TodoList())].Query; a test pins that raw-key spellings keep resolving to the cases.Querytype owns.@MainActormatchesOptimisticEdit.update(the wholeQueryprotocol is isolated).Dogfood — all 4 stringly sites in the repo
[.exact(["todos"])]→[.exact(TodoList())][.exact(["users", .int(id)])]→[.exact(UserByID(id: id))]— the macro (@Query(prefix:)+@Key) owns the key end-to-endEmbeddedTemplates.swiftregenerated (both examples are embedded templates)Tests
New
Invalidation/type-referencedsuite (3): typed spellings produce values identical to the raw-key spellings — so the fully-tested dispatch machinery behind the cases is provably shared — plus exact≠prefix discrimination and the no-overload-capture pin.Verification
🤖 Generated with Claude Code