Skip to content

Commit befaf33

Browse files
authored
fix: Prevent unbounded growth of schemas array in editor (#4401)
* fix: prevent unbounded growth of schemas array * fix: unique schemaUri without uuid
1 parent dc41809 commit befaf33

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

src/shared/components/MonacoEditorESM/Editor.jsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useEffect } from 'react';
12
import { MessageStrip } from '@ui5/webcomponents-react';
23
import { Spinner } from 'shared/components/Spinner/Spinner';
34

@@ -37,17 +38,25 @@ export function Editor({
3738
// prepare autocompletion
3839
const {
3940
setAutocompleteOptions,
41+
cleanupSchema,
4042
error: schemaError,
4143
loading,
4244
} = useAutocompleteWorker({
43-
value,
4445
schemaId,
4546
autocompletionDisabled,
4647
readOnly,
47-
language,
4848
schema,
4949
});
5050

51+
// Cleanup schemas on unmount
52+
useEffect(() => {
53+
return () => {
54+
if (cleanupSchema) {
55+
cleanupSchema();
56+
}
57+
};
58+
}, [cleanupSchema]);
59+
5160
// Initialize editor instance
5261
const { editorInstance, divRef, descriptor } = useCreateEditor({
5362
value,

src/shared/components/MonacoEditorESM/autocompletion/useAutocompleteWorker.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ import { Uri } from 'monaco-editor';
33
import * as monaco from 'monaco-editor';
44
import { configureMonacoYaml } from 'monaco-yaml';
55
import { useGetSchema } from 'hooks/useGetSchema';
6-
import { v4 as uuid } from 'uuid';
76
import YamlWorker from './yaml.worker.js?worker';
87
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
98
import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
109
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
1110

1211
window.MonacoEnvironment = {
13-
getWorker: function (workerId, label) {
12+
getWorker: function (_workerId, label) {
1413
switch (label) {
1514
case 'json':
1615
return new JsonWorker();
@@ -25,17 +24,18 @@ window.MonacoEnvironment = {
2524
},
2625
};
2726

28-
const schemas = [];
27+
// Map to track schemas by schemaId to prevent unbounded growth
28+
const schemasMap = new Map();
2929

3030
export function useAutocompleteWorker({
31-
value,
3231
schemaId: predefinedSchemaId,
3332
autocompletionDisabled,
3433
readOnly,
35-
language,
3634
schema: predefinedSchema,
3735
}) {
3836
const [schemaId] = useState(predefinedSchemaId || Math.random().toString());
37+
// Use schemaId for URI to ensure same resource types share the same schema URI
38+
const schemaUri = `file://kubernetes.io/${schemaId}`;
3939

4040
if (!autocompletionDisabled && !predefinedSchemaId) {
4141
console.warn(
@@ -62,14 +62,16 @@ export function useAutocompleteWorker({
6262
const modelUri = Uri.parse(schemaId);
6363

6464
if (schema) {
65-
schemas.push({
65+
schemasMap.set(schemaId, {
6666
//by monaco-yaml docs, this is not only uri but also a name that must be unique. Resources with the same uri will share one schema.
67-
uri: `file://kubernetes.io/${uuid()}`,
67+
uri: schemaUri,
6868
fileMatch: [String(modelUri)],
6969
schema: schema || {},
7070
});
7171
}
7272

73+
const schemas = Array.from(schemasMap.values());
74+
7375
configureMonacoYaml(monaco, {
7476
enableSchemaRequest: false,
7577
hover: true,
@@ -85,8 +87,13 @@ export function useAutocompleteWorker({
8587
};
8688
}, [schema, schemaId, readOnly]);
8789

90+
const cleanupSchema = useCallback(() => {
91+
schemasMap.delete(schemaId);
92+
}, [schemaId]);
93+
8894
return {
8995
setAutocompleteOptions,
96+
cleanupSchema,
9097
error,
9198
loading,
9299
};

0 commit comments

Comments
 (0)