Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: basePropsGroup use deepclone prevent clone array itself #975

Merged

Conversation

chilingling
Copy link
Member

@chilingling chilingling commented Dec 28, 2024

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • Built its own designer, fully self-validated

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

Background and solution

【问题描述】

  1. 点开物料面板,切换到区块Tab,切换到具体的区块分组(如无,需创建)

  2. 点击添加区块
    image

  3. 选中其中一个区块,点击保存。

  4. 重复 1-3 步骤。

  5. 选中页面中的组件。问题:选中组件卡死(或者很卡)

  6. 选中组件后,发现右侧面板重复了很多很多的基础属性。
    image

【问题分析】

  1. 页面初始化的时候,会调用 patchBaseProps 方法为物料添加基础属性(id、className、ref)。
  2. patchBaseProps 方法会在原物料的基础上,寻找分组名为其他的 props 属性。
    1. 如果存在,则会往原分组属性上插入 basePropGroup
    2. 如果不存在,则会直接往 schemaProperty 插入 basePropGroup注意:这里直接插入的是引用
  3. 区块添加完成之后,会再次方法注册物料,当调用到 patchBaseProps 方法的时候,此时会进入 2.1 的逻辑,即往原分组插入 basePropGroup,但是,此时的原分组与 basePropGroup 相等,相当于自增长。随着物料的迭代,该数组会迅速增长,不断触发 vue 的 proxy 监听,直至栈溢出。

【解决方案】
在 2.1 和 2.2 步骤插入 basePropGroup 的时候,使用深拷贝插入。

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes

    • Improved data handling to prevent unintended mutations when patching base properties.
    • Enhanced data integrity during block registration process.
  • Refactor

    • Introduced deep cloning utility to ensure clean data manipulation.

basePropsGroup 使用深拷贝方式复制自身
Copy link
Contributor

coderabbitai bot commented Dec 28, 2024

Walkthrough

The pull request introduces the deepClone utility function into the useMaterial.js file to enhance data handling within the material composition system. This change ensures that base properties are deeply cloned during the patching process, preventing unintended mutations of the original data structures. The updates affect how base property groups are processed and inserted into schema properties, maintaining data integrity by creating true copies instead of references.

Changes

File Change Summary
packages/plugins/materials/src/composable/useMaterial.js - Added deepClone to imported utilities
- Updated patchBaseProps to utilize deepClone for handling basePropGroup.content and basePropGroup
- Modified registerBlock to include deepClone for property handling

Suggested Labels

refactor-main

Suggested Reviewers

  • kevinmoch

Poem

🐰 A Rabbit's Ode to Deep Cloning 🔬

In the realm of code, where shadows clone,
A deep copy springs, no longer alone!
No more references that twist and turn,
Pure data's path, a lesson to learn.
Hop, hop, hooray for integrity's might! 🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c95144f and 8674bd0.

📒 Files selected for processing (1)
  • packages/plugins/materials/src/composable/useMaterial.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/plugins/materials/src/composable/useMaterial.js

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the bug Something isn't working label Dec 28, 2024
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: 0

🧹 Nitpick comments (1)
packages/plugins/materials/src/composable/useMaterial.js (1)

117-122: LGTM: Proper implementation of deep cloning for base properties

The changes correctly implement deep cloning at all insertion points:

  1. When inserting at the start of the group
  2. When appending at the end of the group
  3. When adding a new base property group

This prevents unintended mutations of the original data structures and ensures proper isolation of property groups.

Consider monitoring the performance impact if dealing with large property groups, as deep cloning can be computationally expensive. In such cases, you might want to:

  1. Add performance metrics to track cloning operations
  2. Consider implementing a more selective cloning strategy for large property groups
  3. Cache cloned results if the same property groups are frequently reused
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f05029 and c95144f.

📒 Files selected for processing (1)
  • packages/plugins/materials/src/composable/useMaterial.js (2 hunks)
🔇 Additional comments (2)
packages/plugins/materials/src/composable/useMaterial.js (2)

28-28: LGTM: Appropriate addition of deepClone utility

The addition of deepClone from the utils module aligns with the PR's objective of preventing array self-cloning issues.


117-122: Verify the usage and impact of deep cloning

Let's verify the implementation and its impact across the codebase.

✅ Verification successful

Let me analyze the deep cloning impact by checking its usage patterns.


Based on the analysis of the deep cloning implementation and usage, I can provide a final assessment:

Deep cloning implementation is safe and optimized

The implementation and usage of deep cloning appears to be well-designed and safe for the following reasons:

  • The deepClone implementation uses a WeakMap to handle circular references, preventing infinite recursion
  • The cloning is done selectively based on type with specific handlers for Arrays, Maps, Sets and Objects
  • The implementation includes comprehensive test coverage for various scenarios including primitive values, nested objects, and circular references
  • Usage is limited to specific necessary cases:
    • Material property group cloning
    • Canvas state management
    • Drag and drop operations

The code shows no concerning patterns:

  • No recursive loops with deep cloning
  • No performance-critical loops using deep cloning
  • Usage is isolated to initialization and state management operations rather than frequent updates

The current implementation in useMaterial.js using deepClone for property groups is appropriate since:

  1. It ensures proper isolation of property definitions
  2. It's used only during initialization/setup rather than in frequent operations
  3. The property groups being cloned are relatively small objects
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Analyze the usage of patchBaseProps and potential deep cloning issues

# Check for all calls to patchBaseProps
echo "Checking patchBaseProps usage patterns..."
rg -A 3 "patchBaseProps\(" 

# Look for potential memory-sensitive contexts
echo "Checking for potential performance-sensitive loops..."
ast-grep --pattern 'for ($loop) {
  $$$
  patchBaseProps($$$)
  $$$
}'

# Check for any TODO/FIXME comments related to performance
echo "Checking for known performance concerns..."
rg -i "todo|fixme|hack|xxx|performance" --type js

Length of output: 70273


Script:

#!/bin/bash
# Check for deepClone usage and implementation
echo "Checking deepClone implementation and usage..."
ast-grep --pattern 'deepClone($$$)'

# Look for any performance-related comments around deepClone
echo "Checking for performance comments around deepClone..."
rg -B2 -A2 "deepClone"

# Check for any loops or recursive patterns with deepClone
echo "Looking for potential recursive or loop patterns with deepClone..."
ast-grep --pattern 'for ($loop) {
  $$$
  deepClone($$$)
  $$$
}'

Length of output: 12346

@hexqi hexqi merged commit 88986b6 into opentiny:release/v2.1.0 Dec 31, 2024
2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 31, 2024
14 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants