chore(app-shell): the dead slot refreshKey parameter is removed (#4549) - #4571
Merged
Conversation
The Studio Data pillar's grid slot declared a `refreshKey` parameter it never read. #4528 removed the dead forward to `ListView` (which declares no such prop) and left the parameter behind for triage. Measured before changing anything: the pillar was never missing its refresh. plugin-view's ObjectView holds ONE `refreshKey` state and emits it to the slot twice — as `schema.refreshTrigger` (:1057) and as a bare `refreshKey` (:1063). `schema.refreshTrigger` is the only one `ListView` reads (its fetch effect's dependency array), and `renderStudioGridList` spreads the slot schema into `ListView`'s schema, so that signal already arrives. Bumping it refetches; severing it in reverse verification turns the new test red. So the parameter is dropped as dead, the comment asserting the opposite is corrected, and the live channel gains pin tests — including one that the refetch keys off the signal VALUE, not renders, and one that the producer really does emit both keys in lockstep. Empty-frontmatter changeset: no behaviour change, and the package's public `index.d.ts` is byte-identical before and after. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Collaborator
Author
|
PM step-7 复核 — ACCEPT (session_017Qqyix2QcnpUC9XeYVDzx3)
Auto-merge armed (squash) — landing verified per the merge-queue discipline. #4567 will be dispatched next, gated on this landing. Generated by Claude Code Generated by Claude Code |
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.
Fixes #4549
The premise did not survive measurement
The card says the Data pillar "has no refreshKey path at all". Measured on current
main: it has one, and it works. The slot's refresh signal reaches the grid today.plugin-view's ObjectView holds one
refreshKeyuseState and hands it to therenderListViewslot twice:schema.refreshTrigger—packages/plugin-view/src/ObjectView.tsx:1057refreshKeyargument — same call,:1063Only the first is a real input.
ListViewlistsschema.refreshTriggerin its fetch effect's dependency array (packages/plugin-list/src/ListView.tsx:1609);refreshKeyis a prop of neitherListViewnor anything it renders — the dead forward #4528 measured and removed. AndrenderStudioGridListspreads the slot schema intoListView's schema, sorefreshTriggerrides that spread. The pillar has been refreshing through it since f591c5d (2026-03-25).So the ruling's preference order lands on option 1 already satisfied: ListView's existing declarative refresh input is not merely available, it is already connected. Nothing needed wiring — no key-fold, no handle, no remount, and no
plugin-listchange. Scroll position, selection and in-progress inline edits were never at risk.Step 0 — does the signal bump on the Studio path?
Yes, via one of the six increment sites. The other five are unreachable from this mount:
:327onMutation auto-subscribeif (renderListView) return;:586handleDelete:591handleBulkDelete:598handleFormSuccessonEdit/onAddRecord, Studio wires both into ListView's toolbar, and a successful submit bumps:608handleRefreshSince it bumps, deletion-for-never-bumping was not the outcome; deletion still is, for the corrected reason that the same number already arrives on a live channel.
What changed
refreshKeyparameter is dropped fromrenderStudioGridList's signature.refreshTriggermust not be dropped or shadowed there.Tests
packages/app-shell/src/views/studio-design/StudioDesignSurface.gridRefresh.test.tsx, driving the real slot function:schema.refreshTriggerandrefreshKeyin lockstep, which is what makes the harness in 1 and 2 faithful rather than a fiction.Reverse verification
A behaviour-neutral deletion has no red-first direction, so the honest check is severing the live channel instead. Adding
refreshTrigger: undefinedafter the spread turns test 1 red:Tests 2 and 3 stay green there, correctly — no refetch at all still satisfies "no storm", and the producer contract is untouched. Restore verified by sha256 (
b09de723c17ed610...).Verification
pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/studio-design/— 25 files, 144 tests passed (the fix(app-shell): the default-inspector family and its panel hosts gate Save on CEL errors (#4527) #4558 panel/inspector suites among them, untouched).pnpm --filter @object-ui/app-shell type-check— both tsc passes clean.origin/mainbaseline. The test-only export tripsreact-refresh/only-export-components(a render-prop callback is not a component), so it carries one narrowly-scoped, justified disable.check:control-bytes,check:phantom-deps,check-changeset-presencegreen; control-byte self-scan over every touched file clean.Changeset
Empty frontmatter — the gate's documented first-class answer for a no-behaviour-change
src/edit. Verified both ways:@object-ui/app-shell's publicdist/index.d.tsis byte-identical before and after (index.tsre-exports a named list, andpackage.jsonexports only.), so the test-only export widens nothing. Noteskip-changesetis not a mechanism in this repo —scripts/__tests__/ci-cd-pipeline-doc.test.ts:184records that neither that workflow nor that label was ever real.Findings filed, not fixed
find()on every render:ListViewdepends on thecolumnsarray by identity, andStudioDesignSurface:2600rebuildstable.fieldswith.map().filter()each render. Measured 1 fetch to 4 across three no-op re-renders; hoisting the array to a stable identity drops it to zero extra. Upstream of this slot and orthogonal to it, so out of scope here — but it is why test 2 hoists its columns, which would otherwise mask the value-vs-render distinction.handleRefreshin plugin-view's ObjectView is declared and never referenced (finding).Generated by Claude Code