Uh oh!
There was an error while loading. Please reload this page.
feat(react,app-shell,plugin-detail,components): data-invalidation bus — refresh data, don't rebuild UI (#2269) - #2274
Merged
Conversation
… — refresh data, don't rebuild UI (#2269) P1 of #2269, plus the P2/P3 guardrails: - @object-ui/react: notifyDataChanged / useDataInvalidation / subscribeDataChanges + useMutationInvalidationBridge(dataSource), which fans every dataSource write (MutationEvent — the bus list views already use) onto one seam. The bus also dispatches the legacy objectui:related-changed window event so pre-bus listeners keep working; notifyRelatedChanged is now a thin alias for writes that bypass the dataSource (row actions). - DELETED both refetch-by-remount keys: key={refreshKey} on RecordDetailView (AppContent) and key={actionRefreshKey} on DetailView. The schema-path pageRecord fetch and DetailView's self-fetch subscribe to the bus and refetch IN PLACE; all nine action-success bumps became precisely-scoped notifyDataChanged calls; undo/redo use the UndoableOperation's own objectName/recordId. - RelatedCountStore wired to the bus + snapshot fixed: getSnapshot returned the same Map reference, so emit() never re-rendered subscribers (pre-existing latent bug — badges only updated by luck) and invalidation left them stale. Snapshot is now a monotonic version; useRelatedCountVersion() drives the probe effect's re-fetch. - P3: app-shell/src/urlParams.ts — single registry of reserved console URL params (recordId/form/formObject/formLink/tab/palette/shortcuts); all literals migrated. - P2: AGENTS.md Commandment #8 — UI-state classification (addressable → URL; preference → storage; ephemeral → component) + 'refresh data, don't rebuild UI'. Browser-verified (showcase, StrictMode): account edit-save on the Related tab → name updates in place, tab kept; child create → subtable refetches via the bridge alone (manual notify removed) and the Related badge re-probes 11 → 12. Unit: +10 bus tests; suites 1679 green; type-check 32/32. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019zKcAtbtxuF9SXYgSzjk9v
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-zhuang
marked this pull request as ready for review
July 5, 2026 08:52
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
概述
落地 #2269 的 P1(失效总线,核心)+ P2(AGENTS.md 状态规则)+ P3(URL 参数注册表)。一句话:"刷数据"不再等于"炸 UI" —— 两个
key=重挂载模式被删除,记录详情/子表/计数徽章全部改为总线驱动的原地重取。架构(基于探索发现的既有先例,不另起炉灶)
代码库已有两半套机制:
DataSource.onMutation(MutationEvent,列表视图已订阅)和related-changed窗口事件 /RelatedCountStore。本 PR 把它们合成一个 seam:变更
@object-ui/react:notifyDataChanged/useDataInvalidation(读端 nonce)/subscribeDataChanges/useMutationInvalidationBridge(dataSource)(console 在 AppContent 挂一次)。AppContent的<RecordDetailView key={refreshKey}>和RecordDetailView的<DetailView key={actionRefreshKey}>。schema 路径的pageRecordfetch 和 legacyDetailView自取 effect 订阅总线原地重取;9 处 action 成功后的 key bump 全部换成精确 scope 的notifyDataChanged;undo/redo 用UndoableOperation自带的objectName/recordId。滚动、折叠分组、tab、进行中的就地编辑从此在保存/action/undo 后全部幸存。RelatedCountStore接总线 + 修一个既有隐性 bug:原getSnapshot返回同一个Map引用 →emit()从不触发订阅者重渲染(徽章更新全靠碰巧的父级渲染),失效后还会永久停留在旧值。快照改为单调 version,新增useRelatedCountVersion()驱动 probe effect 在失效后重新拉取。app-shell/src/urlParams.ts—— 保留参数单点注册(recordId/form/formObject/formLink/tab/palette/shortcuts,含 push-vs-replace 语义表),7 个文件的字面量全部迁入。验证
浏览器端到端(showcase,StrictMode):
单测 +10(总线匹配语义 × 桥接 × 退订);4 包全量 1679 通过;type-check 32/32;changeset(fixed group minor)。
Closes#2269 · Refs #2257 · #2267 · framework#2604 · ADR-0054
🤖 Generated with Claude Code
https://claude.ai/code/session_019zKcAtbtxuF9SXYgSzjk9v
Generated by Claude Code