Skip to content

Expand WaveEnv to cover all the deps in sysinfo.tsx#3019

Merged
sawka merged 7 commits intomainfrom
sawka/waveenv-2
Mar 9, 2026
Merged

Expand WaveEnv to cover all the deps in sysinfo.tsx#3019
sawka merged 7 commits intomainfrom
sawka/waveenv-2

Conversation

@sawka
Copy link
Member

@sawka sawka commented Mar 9, 2026

No description provided.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

Walkthrough

This pull request refactors the view model initialization architecture by consolidating view model constructors from accepting three separate positional parameters (blockId, nodeModel, tabModel) into a single object parameter of type ViewModelInitType. The change introduces WaveEnv as a propagated dependency through the block component factory and view model construction flow. Additionally, the WaveEnv interface is extended with methods for accessing connection status atoms, wave object atoms, and block metadata atoms. Atom APIs are simplified to remove write capabilities from getWaveObjectAtom and getLayoutStateAtomFromTab. The mock environment testing utilities are substantially expanded with new types, helper functions, and lazy initialization patterns. Minor updates include copyright year changes (2025 to 2026) and removal of unused code.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning No description was provided by the author, making it impossible to assess whether a description relates to the changeset. Add a description explaining the purpose of refactoring WaveEnv dependencies and how the ViewModelInitType pattern improves the codebase.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Expand WaveEnv to cover all the deps in sysinfo.tsx' is directly related to the changeset. The PR systematically refactors WaveEnv to include additional dependencies, updates multiple view model constructors to use a new ViewModelInitType pattern, and significantly restructures sysinfo.tsx to inject these dependencies.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sawka/waveenv-2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 9, 2026

Deploying waveterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8073e2a
Status: ✅  Deploy successful!
Preview URL: https://c0401f6c.waveterm.pages.dev
Branch Preview URL: https://sawka-waveenv-2.waveterm.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/app/block/block.tsx (1)

318-331: ⚠️ Potential issue | 🟠 Major

Dispose superseded view models before re-registering them.

Line 323 and Line 350 can replace the cached model after the initial loading render, but the cleanup at Line 329 and Line 356 still closes over the instance from that first render. The real model therefore never gets dispose() on unmount, and view switches leak the old model’s subscriptions/routes.

♻️ One way to fix it
     const bcm = getBlockComponentModel(props.nodeModel.blockId);
     let viewModel = bcm?.viewModel;
-    if (viewModel == null || viewModel.viewType != blockData?.meta?.view) {
+    if (!loading && blockData != null && (viewModel == null || viewModel.viewType != blockData.meta?.view)) {
+        bcm?.viewModel?.dispose?.();
         viewModel = makeViewModel(props.nodeModel.blockId, blockData?.meta?.view, props.nodeModel, tabModel, waveEnv);
         registerBlockComponentModel(props.nodeModel.blockId, { viewModel });
     }
     useEffect(() => {
         return () => {
+            const current = getBlockComponentModel(props.nodeModel.blockId)?.viewModel;
             unregisterBlockComponentModel(props.nodeModel.blockId);
-            viewModel?.dispose?.();
+            current?.dispose?.();
         };
-    }, []);
+    }, [props.nodeModel.blockId]);

Apply the same change in SubBlock.

Also applies to: 345-358

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/app/block/block.tsx` around lines 318 - 331, The cached viewModel
can be replaced after initial render causing the effect cleanup to close over
the old instance and never dispose the newer model; before calling
registerBlockComponentModel(props.nodeModel.blockId, { viewModel }) ensure you
dispose any existing cached model for that blockId (retrieve current model via
getBlockComponentModel and call its dispose()), or store the active viewModel in
a mutable ref and update it when you create a new one so the useEffect cleanup
(unregisterBlockComponentModel and viewModel?.dispose()) always disposes the
latest instance; apply the same fix in SubBlock as well and reference
makeViewModel, registerBlockComponentModel, unregisterBlockComponentModel,
viewModel, dispose, and props.nodeModel.blockId when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/app/view/sysinfo/sysinfo.tsx`:
- Line 266: The call to this.getDefaultData() is unused and should be removed or
its return value should be consumed; either delete the pointless invocation from
the lifecycle/handler where it appears, or capture its return (e.g., const
defaultData = this.getDefaultData()) and use it to initialize component state or
pass it into the consumer that needs default data (look for getDefaultData in
this class and the call site where this.getDefaultData() is invoked). Ensure you
only keep the call if you actually use the produced array (assign to
state/prop/variable) otherwise remove it to eliminate dead code.

---

Outside diff comments:
In `@frontend/app/block/block.tsx`:
- Around line 318-331: The cached viewModel can be replaced after initial render
causing the effect cleanup to close over the old instance and never dispose the
newer model; before calling registerBlockComponentModel(props.nodeModel.blockId,
{ viewModel }) ensure you dispose any existing cached model for that blockId
(retrieve current model via getBlockComponentModel and call its dispose()), or
store the active viewModel in a mutable ref and update it when you create a new
one so the useEffect cleanup (unregisterBlockComponentModel and
viewModel?.dispose()) always disposes the latest instance; apply the same fix in
SubBlock as well and reference makeViewModel, registerBlockComponentModel,
unregisterBlockComponentModel, viewModel, dispose, and props.nodeModel.blockId
when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 35c56c63-a2b3-4e56-9746-bb1a449bce84

📥 Commits

Reviewing files that changed from the base of the PR and between e6e559c and 8073e2a.

📒 Files selected for processing (25)
  • frontend/app/block/block.tsx
  • frontend/app/store/global.ts
  • frontend/app/store/wos.ts
  • frontend/app/tab/tabbar.tsx
  • frontend/app/view/aifilediff/aifilediff.tsx
  • frontend/app/view/helpview/helpview.tsx
  • frontend/app/view/launcher/launcher.tsx
  • frontend/app/view/preview/preview-model.tsx
  • frontend/app/view/quicktipsview/quicktipsview.tsx
  • frontend/app/view/sysinfo/sysinfo.tsx
  • frontend/app/view/term/term-model.ts
  • frontend/app/view/tsunami/tsunami.tsx
  • frontend/app/view/vdom/vdom-model.tsx
  • frontend/app/view/waveai/waveai.tsx
  • frontend/app/view/waveconfig/waveconfig-model.ts
  • frontend/app/view/webview/webview.tsx
  • frontend/app/waveenv/waveenv.ts
  • frontend/app/waveenv/waveenvimpl.ts
  • frontend/layout/lib/layoutAtom.ts
  • frontend/layout/lib/layoutModel.ts
  • frontend/preview/index.html
  • frontend/preview/mock/mockwaveenv.ts
  • frontend/preview/preview.tsx
  • frontend/preview/previews/widgets.preview.tsx
  • frontend/types/custom.d.ts

return;
}
const newData = this.getDefaultData();
this.getDefaultData();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Unused return value from getDefaultData().

The call to this.getDefaultData() creates an array but doesn't use the returned value. Since getDefaultData() has no side effects, this appears to be dead code—possibly a leftover from refactoring.

🔧 Suggested fix: remove or use the return value
-            this.getDefaultData();
             const initialDataItems: DataItem[] = initialData.map(convertWaveEventToDataItem);

Or if the default data is needed:

-            this.getDefaultData();
+            const defaultData = this.getDefaultData();
+            // Use defaultData as needed...
             const initialDataItems: DataItem[] = initialData.map(convertWaveEventToDataItem);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/app/view/sysinfo/sysinfo.tsx` at line 266, The call to
this.getDefaultData() is unused and should be removed or its return value should
be consumed; either delete the pointless invocation from the lifecycle/handler
where it appears, or capture its return (e.g., const defaultData =
this.getDefaultData()) and use it to initialize component state or pass it into
the consumer that needs default data (look for getDefaultData in this class and
the call site where this.getDefaultData() is invoked). Ensure you only keep the
call if you actually use the produced array (assign to state/prop/variable)
otherwise remove it to eliminate dead code.

@sawka sawka merged commit 1aee6e2 into main Mar 9, 2026
8 checks passed
@sawka sawka deleted the sawka/waveenv-2 branch March 9, 2026 23:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant