modern-monaco 0.0.0-beta.1 → 0.0.0-beta.3
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/LICENSE +1 -1
- package/README.md +19 -34
- package/dist/core.js +40 -20
- package/dist/util.js +5 -1
- package/package.json +3 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
> [!WARNING]
|
|
2
|
-
> **This project is currently under active development
|
|
2
|
+
> **This project is currently under active development, the API may change at any time. Use at your own risk.**
|
|
3
|
+
> Please report any issues or feature requests on the [issues](https://github.com/esm-dev/modern-monaco/issues) page.
|
|
3
4
|
|
|
4
5
|
# Modern Monaco
|
|
5
6
|
|
|
@@ -8,7 +9,7 @@ Meeting the modern version of [Monaco Editor](https://www.npmjs.com/package/mona
|
|
|
8
9
|
- Easy to use, no `MonacoEnvironment` setup and web-worker/css loader needed.
|
|
9
10
|
- Using [Shiki](https://shiki.style) for syntax highlighting with tons of grammars and themes.
|
|
10
11
|
- Lazy loading: pre-highlighting code with Shiki while loading `monaco-editor-core` in background.
|
|
11
|
-
- Support
|
|
12
|
+
- Support server-side rendering(SSR).
|
|
12
13
|
- Workspace (edit history, file system provider, persist protocol, etc).
|
|
13
14
|
- Automatically loading `.d.ts` from [esm.sh](https://esm.sh) CDN for type checking.
|
|
14
15
|
- Using [import maps](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) for resolving **bare specifier** imports in JavaScript/TypeScript.
|
|
@@ -17,25 +18,9 @@ Meeting the modern version of [Monaco Editor](https://www.npmjs.com/package/mona
|
|
|
17
18
|
- Inline `html` and `css` in JavaScript/TypeScript.
|
|
18
19
|
- Auto-closing HTML/JSX tags.
|
|
19
20
|
|
|
20
|
-
Planned features:
|
|
21
|
-
|
|
22
|
-
- [ ] Built-in sidebar
|
|
23
|
-
- [ ] file explorer
|
|
24
|
-
- [ ] chat
|
|
25
|
-
- [ ] Workspace persist API
|
|
26
|
-
- [ ] Show a loading indicator while loading the editor
|
|
27
|
-
- [ ] Quick open menu (only if a workspace is provided)
|
|
28
|
-
- [ ] Drag and drop file (only if a workspace is provided)
|
|
29
|
-
- [ ] Display non-code files, like images, videos, etc
|
|
30
|
-
- [ ] VSCode `window.show<XXX>Message` APIs
|
|
31
|
-
- [ ] Emmet
|
|
32
|
-
- [ ] Markdown language service
|
|
33
|
-
- [ ] [Volar](https://github.com/volarjs/volar.js) integration
|
|
34
|
-
- [ ] Support [Shiki JS RegExp Engine](https://shiki.style/guide/regex-engines#javascript-regexp-engine-experimental)
|
|
35
|
-
|
|
36
21
|
## Installation
|
|
37
22
|
|
|
38
|
-
You can install
|
|
23
|
+
You can install `modern-monaco` from NPM:
|
|
39
24
|
|
|
40
25
|
```bash
|
|
41
26
|
npm i modern-monaco typescript
|
|
@@ -44,7 +29,7 @@ npm i modern-monaco typescript
|
|
|
44
29
|
> [!Note]
|
|
45
30
|
> The `typescript` package is required by JavaScript/TypeScript LSP worker. We recommend `typescript@5.5.x` or later.
|
|
46
31
|
|
|
47
|
-
or import it from [esm.sh](https://esm.sh/) in browser without build step:
|
|
32
|
+
or import it from [esm.sh](https://esm.sh/) CDN in browser without build step:
|
|
48
33
|
|
|
49
34
|
```js
|
|
50
35
|
import * from "https://esm.sh/modern-monaco"
|
|
@@ -237,7 +222,7 @@ lazy({
|
|
|
237
222
|
|
|
238
223
|
> [!Note]
|
|
239
224
|
> By default, `modern-monaco` uses `react` or `preact` in the `importmap` script as the `jsxImportSource` option for typescript worker.
|
|
240
|
-
> To use a custom `jsxImportSource` option, add `@jsxRuntime` specifier in the `importmap` script.
|
|
225
|
+
> To use a custom `jsxImportSource` option, add `@jsxRuntime` specifier in the `importmap` script.
|
|
241
226
|
|
|
242
227
|
## Editor Theme & Language Grammars
|
|
243
228
|
|
|
@@ -345,17 +330,17 @@ For manual mode, check [here](https://microsoft.github.io/monaco-editor/docs.htm
|
|
|
345
330
|
|
|
346
331
|
`modern-monaco` by default supports full LSP features for the following languages:
|
|
347
332
|
|
|
348
|
-
-
|
|
349
|
-
-
|
|
350
|
-
-
|
|
351
|
-
-
|
|
333
|
+
- HTML
|
|
334
|
+
- CSS/SCSS/LESS
|
|
335
|
+
- JavaScript/TypeScript
|
|
336
|
+
- JSON
|
|
352
337
|
|
|
353
338
|
Plus, `modern-monaco` also supports features like:
|
|
354
339
|
|
|
355
|
-
-
|
|
356
|
-
-
|
|
357
|
-
-
|
|
358
|
-
-
|
|
340
|
+
- File System Provider for import completions
|
|
341
|
+
- Embedded languages in HTML
|
|
342
|
+
- Inline `html` and `css` in JavaScript/TypeScript.
|
|
343
|
+
- Auto-closing HTML/JSX tags
|
|
359
344
|
|
|
360
345
|
> [!Note]
|
|
361
346
|
> You don't need to set the `MonacoEnvironment.getWorker` for LSP support.
|
|
@@ -401,11 +386,7 @@ export interface LSPLanguageConfig {
|
|
|
401
386
|
}
|
|
402
387
|
```
|
|
403
388
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
[TODO]
|
|
407
|
-
|
|
408
|
-
### Using `core` module
|
|
389
|
+
## Using `core` module
|
|
409
390
|
|
|
410
391
|
`modern-monaco` includes built-in grammars and LSP providers for HTML, CSS, JavaScript/TypeScript, and JSON. If you don't need these features, you can use the `modern-monaco/core` sub-module to reduce the bundle size.
|
|
411
392
|
|
|
@@ -414,3 +395,7 @@ import { lazy } from "modern-monaco/core";
|
|
|
414
395
|
|
|
415
396
|
lazy();
|
|
416
397
|
```
|
|
398
|
+
|
|
399
|
+
## License
|
|
400
|
+
|
|
401
|
+
[MIT License](https://opensource.org/licenses/MIT)
|
package/dist/core.js
CHANGED
|
@@ -22,7 +22,10 @@ var dec = /* @__PURE__ */ new TextDecoder();
|
|
|
22
22
|
function decode(data) {
|
|
23
23
|
return data instanceof Uint8Array ? dec.decode(data) : data;
|
|
24
24
|
}
|
|
25
|
-
function
|
|
25
|
+
function isDigital(v) {
|
|
26
|
+
return typeof v === "number" || typeof v === "string" && /^\d+$/.test(v);
|
|
27
|
+
}
|
|
28
|
+
function debunce(fn, delay) {
|
|
26
29
|
let timer = null;
|
|
27
30
|
return () => {
|
|
28
31
|
if (timer !== null) {
|
|
@@ -34,6 +37,15 @@ function debunce(fn, delay = 500) {
|
|
|
34
37
|
}, delay);
|
|
35
38
|
};
|
|
36
39
|
}
|
|
40
|
+
function promiseWithResolvers() {
|
|
41
|
+
let resolve;
|
|
42
|
+
let reject;
|
|
43
|
+
const promise = new Promise((res, rej) => {
|
|
44
|
+
resolve = res;
|
|
45
|
+
reject = rej;
|
|
46
|
+
});
|
|
47
|
+
return { promise, resolve, reject };
|
|
48
|
+
}
|
|
37
49
|
|
|
38
50
|
// src/core.ts
|
|
39
51
|
import { init as initLS } from "./lsp/language-service.js";
|
|
@@ -80,20 +92,20 @@ async function init(options) {
|
|
|
80
92
|
}
|
|
81
93
|
async function lazy(options, hydrate2) {
|
|
82
94
|
const workspace = options?.workspace;
|
|
95
|
+
const { promise: editorWorkerPromise, resolve: onDidEditorWorkerResolve } = promiseWithResolvers();
|
|
83
96
|
let monacoCore = null;
|
|
84
|
-
let onDidEditorWorkerReady;
|
|
85
|
-
let editorWorkerPromise = new Promise((resolve) => {
|
|
86
|
-
onDidEditorWorkerReady = resolve;
|
|
87
|
-
});
|
|
88
97
|
function load(highlighter) {
|
|
89
98
|
if (monacoCore) {
|
|
90
99
|
return monacoCore;
|
|
91
100
|
}
|
|
92
|
-
return monacoCore = loadMonaco(highlighter, workspace, options?.lsp,
|
|
101
|
+
return monacoCore = loadMonaco(highlighter, workspace, options?.lsp, onDidEditorWorkerResolve).then((m) => monacoCore = m);
|
|
93
102
|
}
|
|
94
103
|
function setStyle(el, style) {
|
|
95
104
|
Object.assign(el.style, style);
|
|
96
105
|
}
|
|
106
|
+
function getAttr(el, name) {
|
|
107
|
+
return el.getAttribute(name);
|
|
108
|
+
}
|
|
97
109
|
customElements.define(
|
|
98
110
|
"monaco-editor",
|
|
99
111
|
class extends HTMLElement {
|
|
@@ -102,7 +114,7 @@ async function lazy(options, hydrate2) {
|
|
|
102
114
|
for (const attrName of this.getAttributeNames()) {
|
|
103
115
|
const key = editorProps.find((k) => k.toLowerCase() === attrName);
|
|
104
116
|
if (key) {
|
|
105
|
-
let value = this
|
|
117
|
+
let value = getAttr(this, attrName);
|
|
106
118
|
if (value === "") {
|
|
107
119
|
value = key === "minimap" || key === "stickyScroll" ? { enabled: true } : true;
|
|
108
120
|
} else {
|
|
@@ -169,18 +181,26 @@ async function lazy(options, hydrate2) {
|
|
|
169
181
|
}
|
|
170
182
|
}
|
|
171
183
|
setStyle(this, { display: "block", position: "relative" });
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if (
|
|
175
|
-
|
|
184
|
+
let widthAttr = getAttr(this, "width");
|
|
185
|
+
let heightAttr = getAttr(this, "height");
|
|
186
|
+
if (isDigital(widthAttr) && isDigital(heightAttr)) {
|
|
187
|
+
const width = Number(widthAttr);
|
|
188
|
+
const height = Number(heightAttr);
|
|
189
|
+
setStyle(this, { width: width + "px", height: height + "px" });
|
|
176
190
|
renderOptions.dimension = { width, height };
|
|
177
191
|
} else {
|
|
178
|
-
|
|
192
|
+
if (isDigital(widthAttr)) {
|
|
193
|
+
widthAttr += "px";
|
|
194
|
+
}
|
|
195
|
+
if (isDigital(heightAttr)) {
|
|
196
|
+
heightAttr += "px";
|
|
197
|
+
}
|
|
198
|
+
this.style.width ||= widthAttr ?? "100%";
|
|
199
|
+
this.style.height ||= heightAttr ?? "100%";
|
|
179
200
|
}
|
|
180
201
|
const containerEl = document.createElement("div");
|
|
181
202
|
containerEl.className = "monaco-editor-container";
|
|
182
|
-
containerEl
|
|
183
|
-
containerEl.style.height = "100%";
|
|
203
|
+
setStyle(containerEl, { width: "100%", height: "100%" });
|
|
184
204
|
this.appendChild(containerEl);
|
|
185
205
|
if (!filename && workspace) {
|
|
186
206
|
if (workspace.history.state.current) {
|
|
@@ -240,7 +260,7 @@ async function lazy(options, hydrate2) {
|
|
|
240
260
|
}
|
|
241
261
|
}
|
|
242
262
|
}
|
|
243
|
-
async function
|
|
263
|
+
async function createEditor() {
|
|
244
264
|
const monaco = await load(highlighter);
|
|
245
265
|
const editor = monaco.editor.create(containerEl, renderOptions);
|
|
246
266
|
if (workspace) {
|
|
@@ -254,8 +274,8 @@ async function lazy(options, hydrate2) {
|
|
|
254
274
|
}
|
|
255
275
|
}
|
|
256
276
|
};
|
|
257
|
-
editor.onDidChangeCursorSelection(debunce(storeViewState));
|
|
258
|
-
editor.onDidScrollChange(debunce(storeViewState));
|
|
277
|
+
editor.onDidChangeCursorSelection(debunce(storeViewState, 500));
|
|
278
|
+
editor.onDidScrollChange(debunce(storeViewState, 500));
|
|
259
279
|
workspace.history.onChange((state) => {
|
|
260
280
|
if (editor.getModel()?.uri.toString() !== state.current) {
|
|
261
281
|
workspace._openTextDocument(state.current, editor);
|
|
@@ -299,7 +319,7 @@ async function lazy(options, hydrate2) {
|
|
|
299
319
|
});
|
|
300
320
|
}
|
|
301
321
|
}
|
|
302
|
-
await
|
|
322
|
+
await createEditor();
|
|
303
323
|
}
|
|
304
324
|
}
|
|
305
325
|
);
|
|
@@ -311,7 +331,7 @@ async function lazy(options, hydrate2) {
|
|
|
311
331
|
function hydrate(options) {
|
|
312
332
|
return lazy(options, true);
|
|
313
333
|
}
|
|
314
|
-
async function loadMonaco(highlighter, workspace, lsp,
|
|
334
|
+
async function loadMonaco(highlighter, workspace, lsp, onDidEditorWorkerResolve) {
|
|
315
335
|
const monaco = await import("./editor-core.js");
|
|
316
336
|
const lspProviders = { ...builtinLSPProviders, ...lsp?.providers };
|
|
317
337
|
workspace?.setupMonaco(monaco);
|
|
@@ -341,7 +361,7 @@ async function loadMonaco(highlighter, workspace, lsp, onDidEditorWorkerReady) {
|
|
|
341
361
|
const worker = createWebWorker(url, void 0);
|
|
342
362
|
if (!provider) {
|
|
343
363
|
const onMessage = (e) => {
|
|
344
|
-
|
|
364
|
+
onDidEditorWorkerResolve?.();
|
|
345
365
|
worker.removeEventListener("message", onMessage);
|
|
346
366
|
};
|
|
347
367
|
worker.addEventListener("message", onMessage);
|
package/dist/util.js
CHANGED
|
@@ -27,7 +27,10 @@ function filenameToURL(filename) {
|
|
|
27
27
|
function isPlainObject(v) {
|
|
28
28
|
return typeof v === "object" && v !== null && v.constructor === Object;
|
|
29
29
|
}
|
|
30
|
-
function
|
|
30
|
+
function isDigital(v) {
|
|
31
|
+
return typeof v === "number" || typeof v === "string" && /^\d+$/.test(v);
|
|
32
|
+
}
|
|
33
|
+
function debunce(fn, delay) {
|
|
31
34
|
let timer = null;
|
|
32
35
|
return () => {
|
|
33
36
|
if (timer !== null) {
|
|
@@ -182,6 +185,7 @@ export {
|
|
|
182
185
|
defineProperty,
|
|
183
186
|
encode,
|
|
184
187
|
filenameToURL,
|
|
188
|
+
isDigital,
|
|
185
189
|
isPlainObject,
|
|
186
190
|
openIDB,
|
|
187
191
|
openIDBCursor,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modern-monaco",
|
|
3
3
|
"description": "A modern version of Monaco Editor",
|
|
4
|
-
"version": "0.0.0-beta.
|
|
4
|
+
"version": "0.0.0-beta.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"./shiki": {
|
|
38
38
|
"import": "./dist/shiki.js"
|
|
39
39
|
},
|
|
40
|
-
"./
|
|
41
|
-
"import": "./dist/
|
|
40
|
+
"./util": {
|
|
41
|
+
"import": "./dist/util.js"
|
|
42
42
|
},
|
|
43
43
|
"./lsp/*": {
|
|
44
44
|
"import": "./dist/lsp/*.js"
|