@coldsmirk/inkstone-monaco 0.9.0 → 0.10.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +71 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -19,7 +19,7 @@ Part of [inkstone](https://github.com/coldsmirk/inkstone). For a drop-in React c
19
19
  pnpm add @coldsmirk/inkstone-monaco monaco-editor
20
20
  ```
21
21
 
22
- `monaco-editor` is a **peer dependency** — your app owns the version. Node.js >= 22 for build / SSR hosts; workers are bundled by your bundler from `new Worker(new URL(...))`, which any Vite / Rollup / webpack 5 setup handles natively.
22
+ `monaco-editor` is a **peer dependency** — your app owns the version. Node.js >= 24 for build / SSR hosts. Workers are bundled from dependency-relative `new Worker(new URL(...))` references; Vite and webpack 5 handle this form natively. Plain Rollup does not emit these workers by itself, so configure worker/asset handling that bundles the referenced modules or implement `getWorker` for every label your app can request.
23
23
 
24
24
  ## Quick start
25
25
 
package/dist/index.js CHANGED
@@ -1,5 +1,40 @@
1
1
  //#region src/host.ts
2
- let hostPromise = null;
2
+ const HOST_PROMISE_KEY = Symbol.for("coldsmirk.inkstone.monaco.hostPromise");
3
+ const NLS_REGISTRY_KEY = Symbol.for("coldsmirk.inkstone.monaco.nlsRegistry");
4
+ async function applyZhCnCatalog() {
5
+ const host = globalThis;
6
+ let registry = host[NLS_REGISTRY_KEY];
7
+ if (!registry) {
8
+ registry = { catalogs: /* @__PURE__ */ new WeakMap() };
9
+ host[NLS_REGISTRY_KEY] = registry;
10
+ }
11
+ const hadPreviousLanguage = Object.hasOwn(host, "_VSCODE_NLS_LANGUAGE");
12
+ const hadPreviousMessages = Object.hasOwn(host, "_VSCODE_NLS_MESSAGES");
13
+ const previousLanguage = host._VSCODE_NLS_LANGUAGE;
14
+ const previousMessages = host._VSCODE_NLS_MESSAGES;
15
+ const previousOwner = registry.owner;
16
+ const owner = {};
17
+ const catalogModule = await import("monaco-editor/esm/nls.messages.zh-cn.js");
18
+ let catalog = registry.catalogs.get(catalogModule);
19
+ if (!catalog) {
20
+ catalog = {
21
+ language: host._VSCODE_NLS_LANGUAGE,
22
+ messages: host._VSCODE_NLS_MESSAGES
23
+ };
24
+ registry.catalogs.set(catalogModule, catalog);
25
+ }
26
+ host._VSCODE_NLS_MESSAGES = catalog.messages;
27
+ host._VSCODE_NLS_LANGUAGE = catalog.language;
28
+ registry.owner = owner;
29
+ return () => {
30
+ if (host[NLS_REGISTRY_KEY] !== registry || registry.owner !== owner || host._VSCODE_NLS_MESSAGES !== catalog.messages || host._VSCODE_NLS_LANGUAGE !== catalog.language) return;
31
+ if (hadPreviousMessages) host._VSCODE_NLS_MESSAGES = previousMessages;
32
+ else Reflect.deleteProperty(host, "_VSCODE_NLS_MESSAGES");
33
+ if (hadPreviousLanguage) host._VSCODE_NLS_LANGUAGE = previousLanguage;
34
+ else Reflect.deleteProperty(host, "_VSCODE_NLS_LANGUAGE");
35
+ registry.owner = previousOwner;
36
+ };
37
+ }
3
38
  function editorWorker() {
4
39
  return new Worker(new URL("workers/editor.worker.js", import.meta.url), { type: "module" });
5
40
  }
@@ -28,19 +63,38 @@ function installHoverGeometryFix() {
28
63
  style.textContent = ".context-view:has(> .workbench-hover-container) { width: max-content !important; }";
29
64
  document.head.append(style);
30
65
  }
66
+ const SUGGEST_GEOMETRY_STYLE_SELECTOR = "style[data-inkstone=\"monaco-suggest-geometry\"]";
67
+ function installSuggestGeometryFix() {
68
+ if (document.querySelector(SUGGEST_GEOMETRY_STYLE_SELECTOR)) return;
69
+ const style = document.createElement("style");
70
+ style.dataset.inkstone = "monaco-suggest-geometry";
71
+ style.textContent = ".monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > span.readMore.codicon.codicon-suggest-more-info::before { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }";
72
+ document.head.append(style);
73
+ }
31
74
  function ensureMonacoHost(options = {}) {
32
- hostPromise ??= (async () => {
75
+ const registry = globalThis;
76
+ const existing = registry[HOST_PROMISE_KEY];
77
+ if (existing) return existing;
78
+ const attempt = (async () => {
33
79
  const { locale = "en", getWorker } = options;
34
- if (locale === "zh-cn") await import("monaco-editor/esm/nls.messages.zh-cn.js");
35
- const monaco = await import("monaco-editor");
36
- globalThis.MonacoEnvironment = { getWorker: (workerId, label) => getWorker?.(workerId, label) ?? builtinGetWorker(label) };
37
- installHoverGeometryFix();
38
- return monaco;
39
- })().catch((error) => {
40
- hostPromise = null;
41
- throw error;
80
+ let restoreNls;
81
+ try {
82
+ if (locale === "zh-cn") restoreNls = await applyZhCnCatalog();
83
+ installHoverGeometryFix();
84
+ installSuggestGeometryFix();
85
+ const monaco = await import("monaco-editor");
86
+ globalThis.MonacoEnvironment = { getWorker: (workerId, label) => getWorker?.(workerId, label) ?? builtinGetWorker(label) };
87
+ return monaco;
88
+ } catch (error) {
89
+ restoreNls?.();
90
+ throw error;
91
+ }
92
+ })();
93
+ registry[HOST_PROMISE_KEY] = attempt;
94
+ attempt.catch(() => {
95
+ if (registry[HOST_PROMISE_KEY] === attempt) registry[HOST_PROMISE_KEY] = void 0;
42
96
  });
43
- return hostPromise;
97
+ return attempt;
44
98
  }
45
99
  //#endregion
46
100
  //#region src/keybindings.ts
@@ -244,10 +298,11 @@ var StreamingEditorController = class {
244
298
  append(text) {
245
299
  if (!this.writing) return;
246
300
  this.buffer += text;
247
- const model = this.editor?.getModel();
248
- if (!this.editor || !model) return;
301
+ const instance = this.editor;
302
+ const model = instance?.getModel();
303
+ if (!instance || !model) return;
249
304
  if (model !== this.synced) {
250
- this.replay(this.editor, model);
305
+ this.replay(instance, model);
251
306
  return;
252
307
  }
253
308
  this.claim(model);
@@ -262,9 +317,10 @@ var StreamingEditorController = class {
262
317
  },
263
318
  text
264
319
  }]);
265
- if (!model.isDisposed()) this.editor.revealLine(model.getLineCount());
320
+ if (this.editor === instance && !model.isDisposed() && instance.getModel() === model) instance.revealLine(model.getLineCount());
266
321
  }
267
322
  end() {
323
+ if (!this.writing) return this.buffer;
268
324
  try {
269
325
  const instance = this.editor;
270
326
  const current = instance?.getModel();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coldsmirk/inkstone-monaco",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Framework-agnostic Monaco assembly: lazy offline host (all language workers bundled, no CDN), opt-in Simplified-Chinese UI via monaco's official NLS catalog, and a streaming editor controller for AI-typed content.",
5
5
  "keywords": [
6
6
  "monaco",