This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 2875c76d55a chore(deps): bump react-ace from 14.0.1 to 15.0.0 in
/superset-frontend (#42833)
2875c76d55a is described below
commit 2875c76d55a3da9dae369724e55bb38daad11b17
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
AuthorDate: Tue Sep 8 17:52:09 2026 -0700
chore(deps): bump react-ace from 14.0.1 to 15.0.0 in /superset-frontend
(#42833)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot]
<49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Code <[email protected]>
---
superset-frontend/package-lock.json | 17 +++----
.../packages/superset-ui-core/package.json | 2 +-
.../AsyncAceEditor/AsyncAceEditor.test.tsx | 55 ++++++++++++++++++++++
3 files changed, 65 insertions(+), 9 deletions(-)
diff --git a/superset-frontend/package-lock.json
b/superset-frontend/package-lock.json
index 92dc5cd0769..f979f6512fa 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -32288,7 +32288,8 @@
"version": "4.4.2",
"resolved":
"https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity":
"sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/lodash.isempty": {
"version": "4.4.0",
@@ -32300,7 +32301,8 @@
"version": "4.5.0",
"resolved":
"https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity":
"sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
@@ -47102,7 +47104,7 @@
"math-expression-evaluator": "^2.0.7",
"parse-ms": "^4.0.0",
"re-resizable": "^6.11.2",
- "react-ace": "^14.0.1",
+ "react-ace": "^15.0.0",
"react-draggable": "^4.7.1",
"react-error-boundary": "^6.1.4",
"react-js-cron": "^6.0.2",
@@ -47203,15 +47205,14 @@
}
},
"packages/superset-ui-core/node_modules/react-ace": {
- "version": "14.0.1",
- "resolved":
"https://registry.npmjs.org/react-ace/-/react-ace-14.0.1.tgz",
- "integrity":
"sha512-z6YAZ20PNf/FqmYEic//G/UK6uw0rn21g58ASgHJHl9rfE4nITQLqthr9rHMVQK4ezwohJbp2dGrZpkq979PYQ==",
+ "version": "15.0.0",
+ "resolved":
"https://registry.npmjs.org/react-ace/-/react-ace-15.0.0.tgz",
+ "integrity":
"sha512-gdmS5ftF0hsbkcrAjZQqYbXwFg5JrHuxjki8mP6Bn9kfa6lHKfZk9sU9EfS0ifQ1CpGCmRxF/VC7GRvlJMBuZw==",
"license": "MIT",
"dependencies": {
"ace-builds": "^1.36.3",
"diff-match-patch": "^1.0.5",
- "lodash.get": "^4.4.2",
- "lodash.isequal": "^4.5.0",
+ "fast-equals": "^5.3.3",
"prop-types": "^15.8.1"
},
"peerDependencies": {
diff --git a/superset-frontend/packages/superset-ui-core/package.json
b/superset-frontend/packages/superset-ui-core/package.json
index d2f1ab64520..a766aa9f982 100644
--- a/superset-frontend/packages/superset-ui-core/package.json
+++ b/superset-frontend/packages/superset-ui-core/package.json
@@ -78,7 +78,7 @@
"math-expression-evaluator": "^2.0.7",
"parse-ms": "^4.0.0",
"re-resizable": "^6.11.2",
- "react-ace": "^14.0.1",
+ "react-ace": "^15.0.0",
"react-draggable": "^4.7.1",
"react-error-boundary": "^6.1.4",
"react-js-cron": "^6.0.2",
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/AsyncAceEditor.test.tsx
b/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/AsyncAceEditor.test.tsx
index db5ac8da798..0af0e62cff2 100644
---
a/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/AsyncAceEditor.test.tsx
+++
b/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/AsyncAceEditor.test.tsx
@@ -604,6 +604,61 @@ test('cleans up event listeners on unmount', async () => {
offSpy.mockRestore();
});
+test('re-applies annotations only when their content actually changes across
renders (react-ace 15 fast-equals regression guard)', async () => {
+ // react-ace's componentDidUpdate decides whether to call
+ // session.setAnnotations() by deep-comparing the new/old `annotations`
+ // prop (lib/ace.js, using an internal deep-equality helper -- lodash's
+ // isEqual through react-ace 14.x, fast-equals's deepEqual from 15.0.0
+ // onward). Superset's own AceEditorProvider/EditorWrapper always pass a
+ // freshly `.map()`-derived annotations array on every render, so this
+ // guards the actual behavior Superset relies on: a same-content-but-
+ // different-reference array must NOT re-trigger setAnnotations (or the
+ // editor would thrash on every keystroke-driven re-render), while a
+ // genuinely different array must still update the editor.
+ const ref = createRef<AceEditor>();
+ const annotationsV1 = [{ row: 0, column: 0, type: 'error', text: 'oops' }];
+
+ const { rerender, container } = render(
+ <SQLEditor ref={ref as React.Ref<never>} annotations={annotationsV1} />,
+ );
+
+ await waitFor(() => {
+ expect(container.querySelector(selector)).toBeInTheDocument();
+ });
+
+ const session = ref.current?.editor?.getSession();
+ expect(session).toBeDefined();
+ if (!session) return;
+
+ // The initial mount already applies annotations via componentDidMount,
+ // not componentDidUpdate, so start observing only from the first update.
+ const setAnnotationsSpy = jest.spyOn(session, 'setAnnotations');
+
+ // Same content, new array/object references -- must be a no-op.
+ const annotationsV1SameContent = [
+ { row: 0, column: 0, type: 'error', text: 'oops' },
+ ];
+ rerender(
+ <SQLEditor
+ ref={ref as React.Ref<never>}
+ annotations={annotationsV1SameContent}
+ />,
+ );
+ expect(setAnnotationsSpy).not.toHaveBeenCalled();
+
+ // Genuinely different content -- must update, with the new value.
+ const annotationsV2 = [
+ { row: 1, column: 2, type: 'warning', text: 'different' },
+ ];
+ rerender(
+ <SQLEditor ref={ref as React.Ref<never>} annotations={annotationsV2} />,
+ );
+ expect(setAnnotationsSpy).toHaveBeenCalledTimes(1);
+ expect(setAnnotationsSpy).toHaveBeenCalledWith(annotationsV2);
+
+ setAnnotationsSpy.mockRestore();
+});
+
test('does not move autocomplete popup if target container is document.body',
async () => {
const ref = createRef<AceEditor>();
const { container } = render(<SQLEditor ref={ref as React.Ref<never>} />);