@typefox/monaco-editor-react 6.12.0 → 7.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to npm module [@typefox/monaco-editor-react](https://www.npmjs.com/package/@typefox/monaco-editor-react) are documented in this file.
4
4
 
5
+ ## [7.0.0] - unreleased
6
+
7
+ - Updated to `monaco-languageclient@10.0.0-next.1`.
8
+ - Dropped `monaco-editor-wrapper`.
9
+
5
10
  ## [6.12.0] - 2025-08-21
6
11
 
7
12
  - Updated to `monaco-languageclient@9.11.0` and `monaco-editor-wrapper@6.12.0`.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # React component for Monaco-Editor and Monaco Languageclient
2
2
 
3
- This packages provides a React component that it based on the [monaco-editor-wrapper](https://www.npmjs.com/package/monaco-editor-wrapper). It behaves nearly the same way as the monaco editor, with the primary difference being that you interact with it through a React component.
3
+ This packages provides a React component that wraps the functionality of [monaco-languageclient](https://www.npmjs.com/package/monaco-languageclient). It behaves nearly the same way as the monaco editor, with the primary difference being that you interact with it through a React component.
4
4
 
5
5
  The [monaco-languageclient](https://github.com/TypeFox/monaco-languageclient) can be activated to connect to a language server either via jsonrpc over a websocket to an exernal server process, or via the Language Server Protocol for the browser where the language server runs in a web worker.
6
6
 
@@ -14,13 +14,15 @@ This is npm package is part of the [monaco-languageclient mono repo](https://git
14
14
 
15
15
  ## Usage
16
16
 
17
- You can import the monaco react component for easy use in an existing React project. Below you can see a quick example of a fully functional implementation in TypeScript. The react component uses the same `UserConfig` approach which is then applied to `monaco-editor-wrapper`.
17
+ You can import the monaco react component for easy use in an existing React project. Below you can see a quick example of a fully functional implementation in TypeScript. The react component uses the same config object approach like `monaco-languageclient`.
18
+
19
+ TODO: Update Example
18
20
 
19
21
  ```tsx
20
22
  import React from 'react';
21
23
  import ReactDOM from 'react-dom/client';
22
24
  import '@codingame/monaco-vscode-python-default-extension';
23
- import { WrapperConfig } from 'monaco-editor-wrapper';
25
+ import { WrapperConfig } from 'monaco-languageclient/editorApp';
24
26
  import { MonacoEditorReactComp } from '@typefox/monaco-editor-react';
25
27
  import { configureDefaultWorkerFactory } from 'monaco-editor-wrapper/workers/workerLoaders';
26
28
 
package/lib/index.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { EditorApp, type EditorAppConfig, type TextContents } from 'monaco-languageclient/editorApp';
2
+ import { type LanguageClientConfigs, LanguageClientsManager } from 'monaco-languageclient/lcwrapper';
3
+ import { type MonacoVscodeApiConfig, MonacoVscodeApiWrapper } from 'monaco-languageclient/vscodeApiWrapper';
4
+ import React, { type CSSProperties } from 'react';
5
+ export type ResolveFc = (value: void | PromiseLike<void>) => void;
6
+ export type MonacoEditorProps = {
7
+ style?: CSSProperties;
8
+ className?: string;
9
+ vscodeApiConfig: MonacoVscodeApiConfig;
10
+ editorAppConfig?: EditorAppConfig;
11
+ languageClientConfigs?: LanguageClientConfigs;
12
+ onVscodeApiInitDone?: (monacoVscodeApiManager: MonacoVscodeApiWrapper) => void;
13
+ onEditorStartDone?: (editorApp?: EditorApp) => void;
14
+ onLanguageClientsStartDone?: (lcsManager?: LanguageClientsManager) => void;
15
+ onTextChanged?: (textChanges: TextContents) => void;
16
+ onError?: (error: Error) => void;
17
+ onDisposeEditor?: () => void;
18
+ onDisposeLanguageClients?: () => void;
19
+ modifiedTextValue?: string;
20
+ originalTextValue?: string;
21
+ };
22
+ export declare const MonacoEditorReactComp: React.FC<MonacoEditorProps>;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACrG,OAAO,EAAE,KAAK,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACrG,OAAO,EAAgC,KAAK,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAC1I,OAAO,KAAK,EAAE,EAAE,KAAK,aAAa,EAA+B,MAAM,OAAO,CAAC;AAE/E,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AAElE,MAAM,MAAM,iBAAiB,GAAG;IAC5B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,qBAAqB,CAAC;IACvC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C,mBAAmB,CAAC,EAAE,CAAC,sBAAsB,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC/E,iBAAiB,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;IACpD,0BAA0B,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC3E,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,IAAI,CAAC;IACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAyL7D,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,153 @@
1
+ /* --------------------------------------------------------------------------------------------
2
+ * Copyright (c) 2024 TypeFox and others.
3
+ * Licensed under the MIT License. See LICENSE in the package root for license information.
4
+ * ------------------------------------------------------------------------------------------ */
5
+ import { EditorApp } from 'monaco-languageclient/editorApp';
6
+ import { LanguageClientsManager } from 'monaco-languageclient/lcwrapper';
7
+ import { getEnhancedMonacoEnvironment, MonacoVscodeApiWrapper } from 'monaco-languageclient/vscodeApiWrapper';
8
+ import React, { useEffect, useRef, useState } from 'react';
9
+ export const MonacoEditorReactComp = (props) => {
10
+ const { style, className, vscodeApiConfig, editorAppConfig, languageClientConfigs, onVscodeApiInitDone, onEditorStartDone, onLanguageClientsStartDone, onTextChanged, onError, onDisposeEditor, onDisposeLanguageClients, modifiedTextValue, originalTextValue } = props;
11
+ const apiWrapperRef = useRef(new MonacoVscodeApiWrapper(vscodeApiConfig));
12
+ const haveEditorService = useRef(true);
13
+ const editorAppRef = useRef(null);
14
+ const lcsManagerRef = useRef(null);
15
+ const containerRef = useRef(null);
16
+ const onTextChangedRef = useRef(onTextChanged);
17
+ const [modifiedCode, setModifiedCode] = useState(modifiedTextValue);
18
+ const [originalCode, setOriginalCode] = useState(originalTextValue);
19
+ const performErrorHandling = (error) => {
20
+ if (onError) {
21
+ onError(error);
22
+ }
23
+ else {
24
+ throw error;
25
+ }
26
+ };
27
+ useEffect(() => {
28
+ // this is only available if EditorService is configured
29
+ if (modifiedTextValue !== undefined && haveEditorService.current) {
30
+ setModifiedCode(modifiedTextValue);
31
+ editorAppRef.current?.updateCode({ modified: modifiedTextValue });
32
+ }
33
+ }, [modifiedTextValue]);
34
+ useEffect(() => {
35
+ // this is only available if EditorService is configured
36
+ if (originalTextValue !== undefined && haveEditorService.current) {
37
+ setOriginalCode(originalTextValue);
38
+ editorAppRef.current?.updateCode({ original: originalTextValue });
39
+ }
40
+ }, [originalTextValue]);
41
+ const awaitGlobal = async () => {
42
+ // await global init if not completed before doing anything else
43
+ const envEnhanced = getEnhancedMonacoEnvironment();
44
+ return (envEnhanced.vscodeApiGlobalInitAwait !== undefined) ? envEnhanced.vscodeApiGlobalInitAwait : Promise.resolve();
45
+ };
46
+ const performGlobalInit = async () => {
47
+ if (containerRef.current === null) {
48
+ performErrorHandling(new Error('No htmlContainer found! Aborting...'));
49
+ }
50
+ const envEnhanced = getEnhancedMonacoEnvironment();
51
+ // init will only performed once
52
+ if (envEnhanced.vscodeApiInitialising !== true) {
53
+ (async () => {
54
+ apiWrapperRef.current.getLogger().debug('GLOBAL INIT');
55
+ await apiWrapperRef.current.init({
56
+ caller: className,
57
+ htmlContainer: containerRef.current
58
+ });
59
+ // set if editor mode is available, otherwise text bindings will not work
60
+ haveEditorService.current = envEnhanced.viewServiceType === 'EditorService';
61
+ onVscodeApiInitDone?.(apiWrapperRef.current);
62
+ })();
63
+ }
64
+ };
65
+ useEffect(() => {
66
+ // always try to perform kick global init
67
+ performGlobalInit();
68
+ (async () => {
69
+ try {
70
+ apiWrapperRef.current.getLogger().debug('INIT');
71
+ await awaitGlobal();
72
+ // it is possible to run without an editorApp, for example when using the ViewsService
73
+ if (haveEditorService.current) {
74
+ editorAppRef.current = new EditorApp(editorAppConfig);
75
+ if (editorAppRef.current.isStarting() === true || editorAppRef.current.isDisposing() === true) {
76
+ await Promise.all([
77
+ editorAppRef.current.getStartingAwait(),
78
+ editorAppRef.current.getDisposingAwait()
79
+ ]);
80
+ }
81
+ editorAppRef.current.registerOnTextChangedCallback((textChanges) => {
82
+ if (textChanges.modified !== undefined) {
83
+ setModifiedCode(textChanges.modified);
84
+ }
85
+ if (textChanges.original !== undefined) {
86
+ setOriginalCode(textChanges.original);
87
+ }
88
+ if (onTextChangedRef.current !== undefined) {
89
+ onTextChangedRef.current(textChanges);
90
+ }
91
+ });
92
+ await editorAppRef.current.start(containerRef.current);
93
+ onEditorStartDone?.(editorAppRef.current);
94
+ // originalTextValue and modifiedTextValue useEffects may happen before
95
+ editorAppRef.current.updateCode({
96
+ original: originalCode,
97
+ modified: modifiedCode
98
+ });
99
+ }
100
+ apiWrapperRef.current.getLogger().debug('INIT DONE');
101
+ }
102
+ catch (error) {
103
+ performErrorHandling(error);
104
+ }
105
+ })();
106
+ }, [editorAppConfig]);
107
+ useEffect(() => {
108
+ // always try to perform kick global init
109
+ performGlobalInit();
110
+ if (languageClientConfigs !== undefined) {
111
+ (async () => {
112
+ try {
113
+ apiWrapperRef.current.getLogger().debug('INIT LC');
114
+ await awaitGlobal();
115
+ if (lcsManagerRef.current === null) {
116
+ lcsManagerRef.current = new LanguageClientsManager(apiWrapperRef.current.getLogger());
117
+ }
118
+ await lcsManagerRef.current.setConfigs(languageClientConfigs);
119
+ await lcsManagerRef.current.start();
120
+ onLanguageClientsStartDone?.(lcsManagerRef.current);
121
+ apiWrapperRef.current.getLogger().debug('INIT LC DONE');
122
+ }
123
+ catch (error) {
124
+ performErrorHandling(error);
125
+ }
126
+ })();
127
+ }
128
+ }, [languageClientConfigs]);
129
+ useEffect(() => {
130
+ // always try to perform kick global init
131
+ performGlobalInit();
132
+ return () => {
133
+ (async () => {
134
+ // dispose editor id used and languageclient if enforced
135
+ try {
136
+ apiWrapperRef.current.getLogger().debug('DISPOSE');
137
+ await editorAppRef.current?.dispose();
138
+ onDisposeEditor?.();
139
+ if (languageClientConfigs?.enforceDispose === true) {
140
+ lcsManagerRef.current?.dispose();
141
+ onDisposeLanguageClients?.();
142
+ }
143
+ }
144
+ catch (error) {
145
+ // The language client may throw an error during disposal, but we want to continue anyway
146
+ performErrorHandling(new Error(`Unexpected error occurred during disposal of the language client: ${error}`));
147
+ }
148
+ })();
149
+ };
150
+ }, []);
151
+ return (React.createElement("div", { ref: containerRef, style: style, className: className }));
152
+ };
153
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typefox/monaco-editor-react",
3
- "version": "6.12.0",
3
+ "version": "7.0.0-next.1",
4
4
  "license": "MIT",
5
5
  "description": "React component for Monaco-Editor and Monaco Languageclient",
6
6
  "keywords": [
@@ -10,30 +10,30 @@
10
10
  "react"
11
11
  ],
12
12
  "type": "module",
13
- "main": "./dist/index.js",
14
- "module": "./dist/index.js",
13
+ "main": "./lib/index.js",
14
+ "module": "./lib/index.js",
15
15
  "exports": {
16
16
  ".": {
17
- "types": "./dist/index.d.ts",
18
- "default": "./dist/index.js"
17
+ "types": "./lib/index.d.ts",
18
+ "default": "./lib/index.js"
19
19
  }
20
20
  },
21
21
  "typesVersions": {
22
22
  "*": {
23
23
  ".": [
24
- "dist/index"
24
+ "lib/index"
25
25
  ]
26
26
  }
27
27
  },
28
28
  "files": [
29
- "dist",
29
+ "lib",
30
30
  "src",
31
31
  "README.md",
32
32
  "CHANGELOG.md",
33
33
  "LICENSE"
34
34
  ],
35
35
  "scripts": {
36
- "clean": "shx rm -fr ./dist ./bundle *.tsbuildinfo",
36
+ "clean": "shx rm -fr ./lib ./bundle *.tsbuildinfo",
37
37
  "compile": " tsc --build tsconfig.src.json",
38
38
  "build": "npm run clean && npm run compile"
39
39
  },
@@ -47,7 +47,6 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@codingame/monaco-vscode-editor-api": "~20.2.1",
50
- "monaco-editor-wrapper": "~6.12.0",
51
50
  "react": ">=18.0.0 || <20.0.0"
52
51
  },
53
52
  "repository": {
package/src/index.tsx CHANGED
@@ -3,82 +3,204 @@
3
3
  * Licensed under the MIT License. See LICENSE in the package root for license information.
4
4
  * ------------------------------------------------------------------------------------------ */
5
5
 
6
- import React, { type CSSProperties, useEffect, useRef } from 'react';
7
- import { MonacoEditorLanguageClientWrapper, type TextContents, type WrapperConfig } from 'monaco-editor-wrapper';
6
+ import { EditorApp, type EditorAppConfig, type TextContents } from 'monaco-languageclient/editorApp';
7
+ import { type LanguageClientConfigs, LanguageClientsManager } from 'monaco-languageclient/lcwrapper';
8
+ import { getEnhancedMonacoEnvironment, type MonacoVscodeApiConfig, MonacoVscodeApiWrapper } from 'monaco-languageclient/vscodeApiWrapper';
9
+ import React, { type CSSProperties, useEffect, useRef, useState } from 'react';
10
+
11
+ export type ResolveFc = (value: void | PromiseLike<void>) => void;
8
12
 
9
13
  export type MonacoEditorProps = {
10
14
  style?: CSSProperties;
11
15
  className?: string;
12
- wrapperConfig: WrapperConfig,
16
+ vscodeApiConfig: MonacoVscodeApiConfig;
17
+ editorAppConfig?: EditorAppConfig;
18
+ languageClientConfigs?: LanguageClientConfigs;
19
+ onVscodeApiInitDone?: (monacoVscodeApiManager: MonacoVscodeApiWrapper) => void;
20
+ onEditorStartDone?: (editorApp?: EditorApp) => void;
21
+ onLanguageClientsStartDone?: (lcsManager?: LanguageClientsManager) => void;
13
22
  onTextChanged?: (textChanges: TextContents) => void;
14
- onLoad?: (wrapper: MonacoEditorLanguageClientWrapper) => void;
15
- onError?: (e: unknown) => void;
23
+ onError?: (error: Error) => void;
24
+ onDisposeEditor?: () => void;
25
+ onDisposeLanguageClients?: () => void;
26
+ modifiedTextValue?: string;
27
+ originalTextValue?: string;
16
28
  }
17
29
 
18
30
  export const MonacoEditorReactComp: React.FC<MonacoEditorProps> = (props) => {
19
31
  const {
20
32
  style,
21
33
  className,
22
- wrapperConfig,
34
+ vscodeApiConfig,
35
+ editorAppConfig,
36
+ languageClientConfigs,
37
+ onVscodeApiInitDone,
38
+ onEditorStartDone,
39
+ onLanguageClientsStartDone,
23
40
  onTextChanged,
24
- onLoad,
25
- onError
41
+ onError,
42
+ onDisposeEditor,
43
+ onDisposeLanguageClients,
44
+ modifiedTextValue,
45
+ originalTextValue
26
46
  } = props;
27
47
 
28
- const wrapperRef = useRef<MonacoEditorLanguageClientWrapper>(new MonacoEditorLanguageClientWrapper());
48
+ const apiWrapperRef = useRef<MonacoVscodeApiWrapper>(new MonacoVscodeApiWrapper(vscodeApiConfig));
49
+ const haveEditorService = useRef(true);
50
+ const editorAppRef = useRef<EditorApp>(null);
51
+ const lcsManagerRef = useRef<LanguageClientsManager>(null);
29
52
  const containerRef = useRef<HTMLDivElement>(null);
30
53
  const onTextChangedRef = useRef(onTextChanged);
31
- onTextChangedRef.current = onTextChanged;
54
+ const [modifiedCode, setModifiedCode] = useState(modifiedTextValue);
55
+ const [originalCode, setOriginalCode] = useState(originalTextValue);
56
+
57
+ const performErrorHandling = (error: Error) => {
58
+ if (onError) {
59
+ onError(error);
60
+ } else {
61
+ throw error;
62
+ }
63
+ };
64
+
65
+ useEffect(() => {
66
+ // this is only available if EditorService is configured
67
+ if (modifiedTextValue !== undefined && haveEditorService.current) {
68
+ setModifiedCode(modifiedTextValue);
69
+ editorAppRef.current?.updateCode({modified: modifiedTextValue});
70
+ }
71
+ }, [modifiedTextValue]);
72
+
73
+ useEffect(() => {
74
+ // this is only available if EditorService is configured
75
+ if (originalTextValue !== undefined && haveEditorService.current) {
76
+ setOriginalCode(originalTextValue);
77
+ editorAppRef.current?.updateCode({original: originalTextValue});
78
+ }
79
+ }, [originalTextValue]);
80
+
81
+ const awaitGlobal = async () => {
82
+ // await global init if not completed before doing anything else
83
+ const envEnhanced = getEnhancedMonacoEnvironment();
84
+ return (envEnhanced.vscodeApiGlobalInitAwait !== undefined) ? envEnhanced.vscodeApiGlobalInitAwait : Promise.resolve();
85
+ };
86
+
87
+ const performGlobalInit = async () => {
88
+ if (containerRef.current === null) {
89
+ performErrorHandling(new Error('No htmlContainer found! Aborting...'));
90
+ }
91
+ const envEnhanced = getEnhancedMonacoEnvironment();
92
+
93
+ // init will only performed once
94
+ if (envEnhanced.vscodeApiInitialising !== true) {
95
+
96
+ (async () => {
97
+ apiWrapperRef.current.getLogger().debug('GLOBAL INIT');
98
+ await apiWrapperRef.current.init({
99
+ caller: className,
100
+ htmlContainer: containerRef.current
101
+ });
102
+
103
+ // set if editor mode is available, otherwise text bindings will not work
104
+ haveEditorService.current = envEnhanced.viewServiceType === 'EditorService';
105
+
106
+ onVscodeApiInitDone?.(apiWrapperRef.current);
107
+ })();
108
+ }
109
+ };
32
110
 
33
111
  useEffect(() => {
112
+ // always try to perform kick global init
113
+ performGlobalInit();
34
114
 
35
115
  (async () => {
36
- if (containerRef.current) {
37
- try {
38
- wrapperConfig.htmlContainer = containerRef.current;
39
- if (wrapperRef.current.isInitializing() || wrapperRef.current.isStarting() || wrapperRef.current.isDisposing()) {
116
+ try {
117
+ apiWrapperRef.current.getLogger().debug('INIT');
118
+ await awaitGlobal();
119
+
120
+ // it is possible to run without an editorApp, for example when using the ViewsService
121
+ if (haveEditorService.current) {
122
+ editorAppRef.current = new EditorApp(editorAppConfig);
123
+ if (editorAppRef.current.isStarting() === true || editorAppRef.current.isDisposing() === true) {
40
124
  await Promise.all([
41
- wrapperRef.current.getInitializingAwait(),
42
- wrapperRef.current.getStartingAwait(),
43
- wrapperRef.current.getDisposingAwait()
125
+ editorAppRef.current.getStartingAwait(),
126
+ editorAppRef.current.getDisposingAwait()
44
127
  ]);
45
128
  }
46
129
 
47
- await wrapperRef.current.init(wrapperConfig);
48
-
49
- wrapperRef.current.registerTextChangedCallback((textChanges) => {
130
+ editorAppRef.current.registerOnTextChangedCallback((textChanges) => {
131
+ if (textChanges.modified !== undefined) {
132
+ setModifiedCode(textChanges.modified);
133
+ }
134
+ if (textChanges.original !== undefined) {
135
+ setOriginalCode(textChanges.original);
136
+ }
50
137
  if (onTextChangedRef.current !== undefined) {
51
138
  onTextChangedRef.current(textChanges);
52
139
  }
53
140
  });
54
- await wrapperRef.current.start();
55
- onLoad?.(wrapperRef.current);
56
- } catch (e) {
57
- if (onError) {
58
- onError(e);
59
- } else {
60
- throw e;
61
- }
141
+ await editorAppRef.current.start(containerRef.current!);
142
+
143
+ onEditorStartDone?.(editorAppRef.current);
144
+
145
+ // originalTextValue and modifiedTextValue useEffects may happen before
146
+ editorAppRef.current.updateCode({
147
+ original: originalCode,
148
+ modified: modifiedCode
149
+ });
62
150
  }
63
- } else {
64
- throw new Error('No htmlContainer found! Aborting...');
151
+ apiWrapperRef.current.getLogger().debug('INIT DONE');
152
+ } catch (error) {
153
+ performErrorHandling(error as Error);
65
154
  }
66
155
  })();
67
- }, [wrapperConfig]);
156
+ }, [editorAppConfig]);
68
157
 
69
158
  useEffect(() => {
70
- const disposeMonaco = async () => {
71
- try {
72
- await wrapperRef.current.dispose();
73
- } catch (error) {
74
- // The language client may throw an error during disposal, but we want to continue anyway
75
- console.error(`Unexpected error occurred during disposal of the language client: ${error}`);
76
- }
77
- };
159
+ // always try to perform kick global init
160
+ performGlobalInit();
161
+
162
+ if (languageClientConfigs !== undefined) {
163
+ (async () => {
164
+ try {
165
+ apiWrapperRef.current.getLogger().debug('INIT LC');
166
+ await awaitGlobal();
167
+
168
+ if (lcsManagerRef.current === null) {
169
+ lcsManagerRef.current = new LanguageClientsManager(apiWrapperRef.current.getLogger());
170
+ }
171
+
172
+ await lcsManagerRef.current.setConfigs(languageClientConfigs);
173
+ await lcsManagerRef.current.start();
174
+
175
+ onLanguageClientsStartDone?.(lcsManagerRef.current);
176
+ apiWrapperRef.current.getLogger().debug('INIT LC DONE');
177
+ } catch (error) {
178
+ performErrorHandling(error as Error);
179
+ }
180
+ })();
181
+ }
182
+ }, [languageClientConfigs]);
183
+
184
+ useEffect(() => {
185
+ // always try to perform kick global init
186
+ performGlobalInit();
78
187
 
79
188
  return () => {
80
189
  (async () => {
81
- await disposeMonaco();
190
+ // dispose editor id used and languageclient if enforced
191
+ try {
192
+ apiWrapperRef.current.getLogger().debug('DISPOSE');
193
+ await editorAppRef.current?.dispose();
194
+ onDisposeEditor?.();
195
+
196
+ if (languageClientConfigs?.enforceDispose === true) {
197
+ lcsManagerRef.current?.dispose();
198
+ onDisposeLanguageClients?.();
199
+ }
200
+ } catch (error) {
201
+ // The language client may throw an error during disposal, but we want to continue anyway
202
+ performErrorHandling(new Error(`Unexpected error occurred during disposal of the language client: ${error}`));
203
+ }
82
204
  })();
83
205
  };
84
206
  }, []);
package/dist/index.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import React, { type CSSProperties } from 'react';
2
- import { MonacoEditorLanguageClientWrapper, type TextContents, type WrapperConfig } from 'monaco-editor-wrapper';
3
- export type MonacoEditorProps = {
4
- style?: CSSProperties;
5
- className?: string;
6
- wrapperConfig: WrapperConfig;
7
- onTextChanged?: (textChanges: TextContents) => void;
8
- onLoad?: (wrapper: MonacoEditorLanguageClientWrapper) => void;
9
- onError?: (e: unknown) => void;
10
- };
11
- export declare const MonacoEditorReactComp: React.FC<MonacoEditorProps>;
12
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,aAAa,EAAqB,MAAM,OAAO,CAAC;AACrE,OAAO,EAAE,iCAAiC,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEjH,MAAM,MAAM,iBAAiB,GAAG;IAC5B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,iCAAiC,KAAK,IAAI,CAAC;IAC9D,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA2E7D,CAAC"}
package/dist/index.js DELETED
@@ -1,66 +0,0 @@
1
- /* --------------------------------------------------------------------------------------------
2
- * Copyright (c) 2024 TypeFox and others.
3
- * Licensed under the MIT License. See LICENSE in the package root for license information.
4
- * ------------------------------------------------------------------------------------------ */
5
- import React, { useEffect, useRef } from 'react';
6
- import { MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper';
7
- export const MonacoEditorReactComp = (props) => {
8
- const { style, className, wrapperConfig, onTextChanged, onLoad, onError } = props;
9
- const wrapperRef = useRef(new MonacoEditorLanguageClientWrapper());
10
- const containerRef = useRef(null);
11
- const onTextChangedRef = useRef(onTextChanged);
12
- onTextChangedRef.current = onTextChanged;
13
- useEffect(() => {
14
- (async () => {
15
- if (containerRef.current) {
16
- try {
17
- wrapperConfig.htmlContainer = containerRef.current;
18
- if (wrapperRef.current.isInitializing() || wrapperRef.current.isStarting() || wrapperRef.current.isDisposing()) {
19
- await Promise.all([
20
- wrapperRef.current.getInitializingAwait(),
21
- wrapperRef.current.getStartingAwait(),
22
- wrapperRef.current.getDisposingAwait()
23
- ]);
24
- }
25
- await wrapperRef.current.init(wrapperConfig);
26
- wrapperRef.current.registerTextChangedCallback((textChanges) => {
27
- if (onTextChangedRef.current !== undefined) {
28
- onTextChangedRef.current(textChanges);
29
- }
30
- });
31
- await wrapperRef.current.start();
32
- onLoad?.(wrapperRef.current);
33
- }
34
- catch (e) {
35
- if (onError) {
36
- onError(e);
37
- }
38
- else {
39
- throw e;
40
- }
41
- }
42
- }
43
- else {
44
- throw new Error('No htmlContainer found! Aborting...');
45
- }
46
- })();
47
- }, [wrapperConfig]);
48
- useEffect(() => {
49
- const disposeMonaco = async () => {
50
- try {
51
- await wrapperRef.current.dispose();
52
- }
53
- catch (error) {
54
- // The language client may throw an error during disposal, but we want to continue anyway
55
- console.error(`Unexpected error occurred during disposal of the language client: ${error}`);
56
- }
57
- };
58
- return () => {
59
- (async () => {
60
- await disposeMonaco();
61
- })();
62
- };
63
- }, []);
64
- return (React.createElement("div", { ref: containerRef, style: style, className: className }));
65
- };
66
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}