modern-monaco 0.0.0-beta.4 → 0.1.0

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/README.md CHANGED
@@ -1,20 +1,20 @@
1
1
  > [!WARNING]
2
- > **This project is currently under active development, the API may change at any time. Use at your own risk.**
2
+ > **This project is currently under active development. The API may change at any time. Use at your own risk.**
3
3
  > Please report any issues or feature requests on the [issues](https://github.com/esm-dev/modern-monaco/issues) page.
4
4
 
5
5
  # Modern Monaco
6
6
 
7
- Meeting the modern version of [Monaco Editor](https://www.npmjs.com/package/monaco-editor):
7
+ Meet the modern version of [Monaco Editor](https://www.npmjs.com/package/monaco-editor):
8
8
 
9
- - Easy to use, no `MonacoEnvironment` setup and web-worker/css loader needed.
10
- - Using [Shiki](https://shiki.style) for syntax highlighting with tons of grammars and themes.
11
- - Lazy loading: pre-highlighting code with Shiki while loading `monaco-editor-core` in background.
12
- - Support server-side rendering(SSR).
13
- - Workspace (edit history, file system provider, persist protocol, etc).
14
- - Automatically loading `.d.ts` from [esm.sh](https://esm.sh) CDN for type checking.
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.
9
+ - Easy to use, no `MonacoEnvironment` setup, web workers, or CSS loaders required.
10
+ - Uses [Shiki](https://shiki.style) for syntax highlighting with extensive grammars and themes.
11
+ - Lazy loading: pre-highlight code with Shiki while loading `monaco-editor-core` in the background.
12
+ - Supports server-side rendering (SSR).
13
+ - Workspace features (edit history, file system provider, persist protocol, etc.).
14
+ - Automatically loads `.d.ts` files from [esm.sh](https://esm.sh) CDN for type checking.
15
+ - Uses [import maps](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) for resolving **bare specifier** imports in JavaScript/TypeScript.
16
16
  - VSCode `window` APIs like `showInputBox`, `showQuickPick`, etc.
17
- - Embedded languages(importmap/CSS/JavaScript) in HTML.
17
+ - Embedded languages (importmap/CSS/JavaScript) in HTML.
18
18
  - Inline `html` and `css` in JavaScript/TypeScript.
19
19
  - Auto-closing HTML/JSX tags.
20
20
 
@@ -27,9 +27,9 @@ npm i modern-monaco typescript
27
27
  ```
28
28
 
29
29
  > [!Note]
30
- > The `typescript` package is required by JavaScript/TypeScript LSP worker. We recommend `typescript@5.5.x` or later.
30
+ > The `typescript` package is required by the JavaScript/TypeScript LSP worker. We recommend `typescript@5.5.x` or later.
31
31
 
32
- or import it from [esm.sh](https://esm.sh/) CDN in browser without build step:
32
+ Or import it from [esm.sh](https://esm.sh/) CDN in the browser without a build step:
33
33
 
34
34
  ```js
35
35
  import * from "https://esm.sh/modern-monaco"
@@ -40,38 +40,46 @@ import * from "https://esm.sh/modern-monaco"
40
40
  `modern-monaco` provides three modes to create a browser-based code editor:
41
41
 
42
42
  - **Lazy**: pre-highlight code with Shiki while loading the `editor-core.js` in the background.
43
- - **SSR**: render a mock editor on the server side, and hydrate it on the client side.
44
- - **Manual**: create a monaco editor instance manually.
43
+ - **SSR**: render a mock editor on the server side and hydrates it on the client side.
44
+ - **Manual**: create a Monaco editor instance manually.
45
45
 
46
46
  ### Lazy Mode
47
47
 
48
- [monaco-editor](https://www.npmjs.com/package/monaco-editor) is a large package with extra CSS/Worker modules, and needs the `MonacoEnvironment` setup for language service support. `modern-monaco` provides a lazy but smart way to load the editor modules on demand.
48
+ [monaco-editor](https://www.npmjs.com/package/monaco-editor) is a large package with additional CSS/Worker modules that requires `MonacoEnvironment` setup for language service support. `modern-monaco` provides a simple yet smart way to load editor modules on demand.
49
49
 
50
- By pre-highlighting code with Shiki while loading editor modules in the background, `modern-monaco` can reduce the loading screen time.
50
+ By pre-highlighting code with Shiki while loading editor modules in the background, `modern-monaco` can significantly reduce loading screen time.
51
+
52
+ To create a Monaco editor lazily, you need to add a `<monaco-editor>` custom element in your app's HTML, then call the `lazy` function from modern-monaco. You also need to provide a workspace object to manage files for the editor.
51
53
 
52
54
  ```html
55
+ <!-- index.html -->
53
56
  <monaco-editor></monaco-editor>
57
+ <script src="app.js" type="module"></script>
58
+ ```
54
59
 
55
- <script type="module">
56
- import { lazy, Workspace } from "modern-monaco";
60
+ ```js
61
+ // app.js
62
+ import { lazy, Workspace } from "modern-monaco";
57
63
 
58
- // create a workspace with initial files
59
- const workspace = new Workspace({
60
- initialFiles: {
61
- "index.html": `<html><head><title>Hello, world!</title></head><body><script src="main.js"></script></body></html>`,
62
- "main.js": `console.log("Hello, world!")`
63
- },
64
- entryFile: "index.html",
65
- });
64
+ // create a workspace with initial files
65
+ const workspace = new Workspace({
66
+ initialFiles: {
67
+ "index.html": `<html>...</body></html>`,
68
+ "main.js": `console.log("Hello, world!")`
69
+ },
70
+ entryFile: "index.html",
71
+ });
66
72
 
67
- // initialize the editor lazily
68
- lazy({ workspace });
69
- </script>
73
+ // initialize the editor lazily
74
+ await lazy({ workspace });
75
+
76
+ // open a file in the workspace
77
+ workspace.openTextDocument("main.js");
70
78
  ```
71
79
 
72
80
  ### SSR Mode
73
81
 
74
- SSR mode returns an instant pre-rendered editor on the server side, and hydrate it on the client side.
82
+ SSR mode returns an instant pre-rendered editor on the server side and hydrates it on the client side.
75
83
 
76
84
  ```js
77
85
  import { renderToWebComponent } from "modern-monaco/ssr";
@@ -103,7 +111,7 @@ export default {
103
111
 
104
112
  ### Manual Mode
105
113
 
106
- You can also create a [monaco editor](https://microsoft.github.io/monaco-editor/docs.html) instance manually.
114
+ You can also create a [Monaco editor](https://microsoft.github.io/monaco-editor/docs.html) instance manually. It loads themes and language grammars automatically.
107
115
 
108
116
  ```html
109
117
  <div id="editor"></div>
@@ -114,7 +122,7 @@ You can also create a [monaco editor](https://microsoft.github.io/monaco-editor/
114
122
  // load monaco-editor-core.js
115
123
  const monaco = await init();
116
124
 
117
- // create a monaco editor instance
125
+ // create a Monaco editor instance
118
126
  const editor = monaco.editor.create(document.getElementById("editor"));
119
127
 
120
128
  // create and attach a model to the editor
@@ -124,21 +132,21 @@ You can also create a [monaco editor](https://microsoft.github.io/monaco-editor/
124
132
 
125
133
  ## Using Workspace
126
134
 
127
- `modern-monaco` provides VSCode-like workspace features, like edit history, file system provider, etc.
135
+ `modern-monaco` provides VSCode-like workspace features, such as edit history, file system provider, and more.
128
136
 
129
137
  ```js
130
138
  import { lazy, Workspace } from "modern-monaco";
131
139
 
132
140
  // 1. create a workspace with initial files
133
141
  const workspace = new Workspace({
134
- /** the name of the workspace, used for project isolation, default is "default". */
142
+ /** The name of the workspace, used for project isolation. Default is "default". */
135
143
  name: "project-name",
136
- /** initial files in the workspace. */
144
+ /** Initial files in the workspace. */
137
145
  initialFiles: {
138
146
  "index.html": `<html><head><title>Hello, world!</title></head><body><script src="main.js"></script></body></html>`,
139
147
  "main.js": `console.log("Hello, world!")`,
140
148
  },
141
- /** file to open when the editor is loaded for the first time. */
149
+ /** File to open when the editor is loaded for the first time. */
142
150
  entryFile: "index.html",
143
151
  });
144
152
 
@@ -205,7 +213,7 @@ const workspace = new Workspace({
205
213
  });
206
214
  ```
207
215
 
208
- You can also provide an importmap object as the `lsp.typescript.importMap` option in the `lazy`, `init`, or `hydrate` function.
216
+ You can also provide an import map object as the `lsp.typescript.importMap` option in the `lazy`, `init`, or `hydrate` functions.
209
217
 
210
218
  ```js
211
219
  lazy({
@@ -221,22 +229,22 @@ lazy({
221
229
  ```
222
230
 
223
231
  > [!Note]
224
- > By default, `modern-monaco` uses `react` or `preact` in the `importmap` script as the `jsxImportSource` option for typescript worker.
225
- > To use a custom `jsxImportSource` option, add `@jsxRuntime` specifier in the `importmap` script.
232
+ > By default, `modern-monaco` uses `react` or `preact` in the `importmap` script as the `jsxImportSource` option for the TypeScript worker.
233
+ > To use a custom `jsxImportSource` option, add the `@jsxRuntime` specifier in the `importmap` script.
226
234
 
227
235
  ## Editor Theme & Language Grammars
228
236
 
229
- `modern-monaco` uses [Shiki](https://shiki.style) for syntax highlighting with tons of grammars and themes. By default, it loads themes and grammars from esm.sh on demand.
237
+ `modern-monaco` uses [Shiki](https://shiki.style) for syntax highlighting with extensive grammars and themes. By default, it loads themes and grammars from esm.sh on demand.
230
238
 
231
239
  ### Setting the Editor Theme
232
240
 
233
- To set the theme of the editor, you can add a `theme` attribute to the `<monaco-editor>` element.
241
+ To set the editor theme, you can add a `theme` attribute to the `<monaco-editor>` element.
234
242
 
235
243
  ```html
236
244
  <monaco-editor theme="OneDark-Pro"></monaco-editor>
237
245
  ```
238
246
 
239
- or set it in the `lazy`, `init`, or `hydrate` function.
247
+ Or set it in the `lazy`, `init`, or `hydrate` function.
240
248
 
241
249
  ```js
242
250
  lazy({
@@ -253,13 +261,13 @@ lazy({
253
261
  import OneDark from "tm-themes/themes/OneDark-Pro.json" with { type: "json" };
254
262
 
255
263
  lazy({
256
- theme: OneDark
264
+ theme: OneDark,
257
265
  });
258
266
  ```
259
267
 
260
268
  ### Pre-loading Language Grammars
261
269
 
262
- By default, `modern-monaco` loads language grammars when a specific language mode is attached in the editor. You can also pre-load language grammars by adding the `langs` option to the `lazy`, `init`, or `hydrate` function. The `langs` option is an array of language grammars, which can be a language grammar object, a language ID, or a URL to the language grammar.
270
+ By default, `modern-monaco` loads language grammars when a specific language mode is attached to the editor. You can also pre-load language grammars by adding the `langs` option to the `lazy`, `init`, or `hydrate` functions. The `langs` option is an array of language grammars, which can be a language grammar object, a language ID, or a URL to the language grammar.
263
271
 
264
272
  ```js
265
273
  import markdown from "tm-grammars/markdown.json" with { type: "json" };
@@ -278,7 +286,7 @@ lazy({
278
286
  // load language grammar from a local file
279
287
  "/assets/mylang.json",
280
288
 
281
- // use `tm-grammars` package without extra http requests, but increases the bundle size
289
+ // use `tm-grammars` package without extra HTTP requests, but increases the bundle size
282
290
  markdown,
283
291
 
284
292
  // dynamically import
@@ -291,14 +299,14 @@ lazy({
291
299
  patterns: [/* ... */],
292
300
  },
293
301
  ],
294
- // the CDN for loading language grammars and themes, default is "https://esm.sh"
295
- tmDownloadCDN: "https://unpkg.com",
302
+ // The CDN for loading language grammars and themes. Default is "https://esm.sh"
303
+ tmDownloadCDN: "https://esm.sh",
296
304
  });
297
305
  ```
298
306
 
299
307
  ## Editor Options
300
308
 
301
- You can set the editor options in the `<monaco-editor>` element as attributes. The editor options are the same as the [`editor.EditorOptions`](https://microsoft.github.io/monaco-editor/docs.html#variables/editor.EditorOptions.html).
309
+ You can set editor options as attributes in the `<monaco-editor>` element. The editor options are the same as [`editor.EditorOptions`](https://microsoft.github.io/monaco-editor/docs.html#variables/editor.EditorOptions.html).
302
310
 
303
311
  ```html
304
312
  <monaco-editor
@@ -308,7 +316,7 @@ You can set the editor options in the `<monaco-editor>` element as attributes. T
308
316
  ></monaco-editor>
309
317
  ```
310
318
 
311
- For SSR mode, you can set the editor options in the `renderToWebComponent` function.
319
+ For SSR mode, you can set editor options in the `renderToWebComponent` function.
312
320
 
313
321
  ```js
314
322
  import { renderToWebComponent } from "modern-monaco/ssr";
@@ -335,20 +343,20 @@ For manual mode, check [here](https://microsoft.github.io/monaco-editor/docs.htm
335
343
  - JavaScript/TypeScript
336
344
  - JSON
337
345
 
338
- Plus, `modern-monaco` also supports features like:
346
+ Additionally, `modern-monaco` supports features like:
339
347
 
340
348
  - File System Provider for import completions
341
349
  - Embedded languages in HTML
342
- - Inline `html` and `css` in JavaScript/TypeScript.
350
+ - Inline `html` and `css` in JavaScript/TypeScript
343
351
  - Auto-closing HTML/JSX tags
344
352
 
345
353
  > [!Note]
346
- > You don't need to set the `MonacoEnvironment.getWorker` for LSP support.
347
- > `modern-monaco` will automatically load the required LSP workers.
354
+ > You don't need to set `MonacoEnvironment.getWorker` for LSP support.
355
+ > `modern-monaco` automatically loads the required LSP workers.
348
356
 
349
- ### LSP language configuration
357
+ ### LSP Language Configuration
350
358
 
351
- You can configure built-in LSPs in the `lazy`, `init`, or `hydrate` function.
359
+ You can configure built-in LSPs in the `lazy`, `init`, or `hydrate` functions.
352
360
 
353
361
  ```js
354
362
  lazy({
@@ -386,7 +394,7 @@ export interface LSPLanguageConfig {
386
394
  }
387
395
  ```
388
396
 
389
- ## Using `core` module
397
+ ## Using the `core` Module
390
398
 
391
399
  `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.
392
400
 
package/dist/core.js CHANGED
@@ -91,25 +91,15 @@ async function init(options) {
91
91
  return loadMonaco(hightlighter, options?.workspace, options?.lsp);
92
92
  }
93
93
  async function lazy(options, hydrate2) {
94
- const workspace = options?.workspace;
95
94
  const { promise: editorWorkerPromise, resolve: onDidEditorWorkerResolve } = promiseWithResolvers();
96
- let monacoCore = null;
97
- function load(highlighter) {
98
- if (monacoCore) {
99
- return monacoCore;
100
- }
101
- return monacoCore = loadMonaco(highlighter, workspace, options?.lsp, onDidEditorWorkerResolve).then((m) => monacoCore = m);
102
- }
103
- function setStyle(el, style) {
104
- Object.assign(el.style, style);
105
- }
106
- function getAttr(el, name) {
107
- return el.getAttribute(name);
108
- }
95
+ const getAttr = (el, name) => el.getAttribute(name);
96
+ const setStyle = (el, style) => Object.assign(el.style, style);
97
+ let monacoPromise = null;
109
98
  customElements.define(
110
99
  "monaco-editor",
111
100
  class extends HTMLElement {
112
101
  async connectedCallback() {
102
+ const workspace = options?.workspace;
113
103
  const renderOptions = {};
114
104
  for (const attrName of this.getAttributeNames()) {
115
105
  const key = editorProps.find((k) => k.toLowerCase() === attrName);
@@ -261,7 +251,7 @@ async function lazy(options, hydrate2) {
261
251
  }
262
252
  }
263
253
  async function createEditor() {
264
- const monaco = await load(highlighter);
254
+ const monaco = await (monacoPromise ?? (monacoPromise = loadMonaco(highlighter, workspace, options?.lsp, onDidEditorWorkerResolve)));
265
255
  const editor = monaco.editor.create(containerEl, renderOptions);
266
256
  if (workspace) {
267
257
  const storeViewState = () => {
@@ -324,9 +314,6 @@ async function lazy(options, hydrate2) {
324
314
  }
325
315
  );
326
316
  await editorWorkerPromise;
327
- return {
328
- workspace
329
- };
330
317
  }
331
318
  function hydrate(options) {
332
319
  return lazy(options, true);
package/dist/index.js CHANGED
@@ -715,7 +715,7 @@ var builtinLSPProviders = {
715
715
  }
716
716
  };
717
717
 
718
- // node_modules/.pnpm/tm-grammars@1.24.1/node_modules/tm-grammars/grammars/html.json
718
+ // node_modules/.pnpm/tm-grammars@1.24.3/node_modules/tm-grammars/grammars/html.json
719
719
  var html_default = {
720
720
  displayName: "HTML",
721
721
  injections: {
@@ -3344,7 +3344,7 @@ var html_default = {
3344
3344
  scopeName: "text.html.basic"
3345
3345
  };
3346
3346
 
3347
- // node_modules/.pnpm/tm-grammars@1.24.1/node_modules/tm-grammars/grammars/css.json
3347
+ // node_modules/.pnpm/tm-grammars@1.24.3/node_modules/tm-grammars/grammars/css.json
3348
3348
  var css_default = {
3349
3349
  displayName: "CSS",
3350
3350
  name: "css",
@@ -5206,7 +5206,7 @@ var css_default = {
5206
5206
  scopeName: "source.css"
5207
5207
  };
5208
5208
 
5209
- // node_modules/.pnpm/tm-grammars@1.24.1/node_modules/tm-grammars/grammars/javascript.json
5209
+ // node_modules/.pnpm/tm-grammars@1.24.3/node_modules/tm-grammars/grammars/javascript.json
5210
5210
  var javascript_default = {
5211
5211
  displayName: "JavaScript",
5212
5212
  name: "javascript",
@@ -11204,7 +11204,7 @@ var javascript_default = {
11204
11204
  scopeName: "source.js"
11205
11205
  };
11206
11206
 
11207
- // node_modules/.pnpm/tm-grammars@1.24.1/node_modules/tm-grammars/grammars/typescript.json
11207
+ // node_modules/.pnpm/tm-grammars@1.24.3/node_modules/tm-grammars/grammars/typescript.json
11208
11208
  var typescript_default = {
11209
11209
  displayName: "TypeScript",
11210
11210
  name: "typescript",
@@ -16953,7 +16953,7 @@ var typescript_default = {
16953
16953
  scopeName: "source.ts"
16954
16954
  };
16955
16955
 
16956
- // node_modules/.pnpm/tm-grammars@1.24.1/node_modules/tm-grammars/grammars/jsx.json
16956
+ // node_modules/.pnpm/tm-grammars@1.24.3/node_modules/tm-grammars/grammars/jsx.json
16957
16957
  var jsx_default = {
16958
16958
  displayName: "JSX",
16959
16959
  name: "jsx",
@@ -22951,7 +22951,7 @@ var jsx_default = {
22951
22951
  scopeName: "source.js.jsx"
22952
22952
  };
22953
22953
 
22954
- // node_modules/.pnpm/tm-grammars@1.24.1/node_modules/tm-grammars/grammars/tsx.json
22954
+ // node_modules/.pnpm/tm-grammars@1.24.3/node_modules/tm-grammars/grammars/tsx.json
22955
22955
  var tsx_default = {
22956
22956
  displayName: "TSX",
22957
22957
  name: "tsx",
@@ -28949,7 +28949,7 @@ var tsx_default = {
28949
28949
  scopeName: "source.tsx"
28950
28950
  };
28951
28951
 
28952
- // node_modules/.pnpm/tm-grammars@1.24.1/node_modules/tm-grammars/grammars/json.json
28952
+ // node_modules/.pnpm/tm-grammars@1.24.3/node_modules/tm-grammars/grammars/json.json
28953
28953
  var json_default = {
28954
28954
  displayName: "JSON",
28955
28955
  name: "json",