stream-monaco 0.0.10 → 0.0.13
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 +3 -1
- package/README.zh-CN.md +4 -0
- package/dist/index.cjs +93 -28
- package/dist/index.js +93 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,9 @@ The package exports helpers around theme/highlighter for advanced use:
|
|
|
34
34
|
- `registerMonacoThemes(themes, languages): Promise<Highlighter>` — create or reuse a Shiki highlighter and register themes to Monaco. Returns a Promise resolving to the highlighter for reuse (e.g., rendering snippets).
|
|
35
35
|
- `getOrCreateHighlighter(themes, languages): Promise<Highlighter>` — get or create a highlighter (managed by internal cache). If you need to call `codeToHtml` or `setTheme` manually, use this and handle loading/errors.
|
|
36
36
|
|
|
37
|
-
Note:
|
|
37
|
+
Note:
|
|
38
|
+
- If the target theme is already included in the `themes` you passed to `useMonaco()`, calling `monaco.editor.setTheme(themeName)` is fine.
|
|
39
|
+
- If you switch to a theme that was not pre-registered (e.g. dynamic theme name like `andromeeda`), prefer `await setTheme(themeName)` from `useMonaco()`. It will ensure the theme is registered, and when possible it will also try to `loadTheme` on the underlying Shiki highlighter to avoid "Theme not found, you may need to load it first" errors.
|
|
38
40
|
|
|
39
41
|
Config: `useMonaco()` does not auto-sync an external Shiki highlighter; if you need external Shiki snippets to follow theme changes, call `getOrCreateHighlighter(...)` and `highlighter.setTheme(...)` yourself.
|
|
40
42
|
|
package/README.zh-CN.md
CHANGED
|
@@ -27,6 +27,10 @@ IMPORTANT: Since v0.0.32 the library enables a default time-based throttle for `
|
|
|
27
27
|
|
|
28
28
|
注意:如果你只使用 Monaco 编辑器并在 `createEditor` 时传入了全量 `themes`,通常只需调用 `monaco.editor.setTheme(themeName)` 即可。
|
|
29
29
|
|
|
30
|
+
补充:如果你要切换到一个**不在初始 `themes` 列表里的主题**(例如运行时才决定的 `andromeeda`),建议使用 `useMonaco()` 返回的 `await setTheme(themeName)`,而不是直接调用 `monaco.editor.setTheme(themeName)`。
|
|
31
|
+
|
|
32
|
+
`setTheme()` 会确保主题被注册;并且在可能的情况下,会对底层 Shiki highlighter 进行一次 `loadTheme(themeName)` 的兜底,避免出现 `Theme ... not found, you may need to load it first` 这类“主题未加载”的错误。
|
|
33
|
+
|
|
30
34
|
配置:`useMonaco()` 不会自动同步 Shiki highlighter;如果你需要在切换主题时同步页面中独立的 Shiki 渲染,请手动使用 `getOrCreateHighlighter(...)` 并调用高亮器实例的 `setTheme`。
|
|
31
35
|
|
|
32
36
|
### 安装
|
package/dist/index.cjs
CHANGED
|
@@ -1993,9 +1993,7 @@ function arraysEqual(a, b) {
|
|
|
1993
1993
|
|
|
1994
1994
|
//#endregion
|
|
1995
1995
|
//#region src/utils/registerMonacoThemes.ts
|
|
1996
|
-
let themesRegistered = false;
|
|
1997
1996
|
let languagesRegistered = false;
|
|
1998
|
-
let currentThemes = [];
|
|
1999
1997
|
let currentLanguages = [];
|
|
2000
1998
|
let themeRegisterPromise = null;
|
|
2001
1999
|
let registrationQueue = Promise.resolve();
|
|
@@ -2008,6 +2006,54 @@ function setThemeRegisterPromise(p) {
|
|
|
2008
2006
|
return themeRegisterPromise = p;
|
|
2009
2007
|
}
|
|
2010
2008
|
const highlighterCache = /* @__PURE__ */ new Map();
|
|
2009
|
+
let monacoHighlighterPromise = null;
|
|
2010
|
+
let lastPatchedHighlighter = null;
|
|
2011
|
+
const monacoThemeByKey = /* @__PURE__ */ new Map();
|
|
2012
|
+
const monacoLanguageSet = /* @__PURE__ */ new Set();
|
|
2013
|
+
function themeKey(t) {
|
|
2014
|
+
return typeof t === "string" ? t : t.name ?? JSON.stringify(t);
|
|
2015
|
+
}
|
|
2016
|
+
async function ensureMonacoHighlighter(themes, languages$1) {
|
|
2017
|
+
for (const t of themes) monacoThemeByKey.set(themeKey(t), t);
|
|
2018
|
+
for (const l of languages$1) monacoLanguageSet.add(l);
|
|
2019
|
+
if (!monacoHighlighterPromise) {
|
|
2020
|
+
const initialThemes = Array.from(monacoThemeByKey.values());
|
|
2021
|
+
const initialLangs = Array.from(monacoLanguageSet.values());
|
|
2022
|
+
monacoHighlighterPromise = (0, shiki.createHighlighter)({
|
|
2023
|
+
themes: initialThemes,
|
|
2024
|
+
langs: initialLangs
|
|
2025
|
+
}).then((h$1) => h$1);
|
|
2026
|
+
}
|
|
2027
|
+
const h = await monacoHighlighterPromise;
|
|
2028
|
+
const wantsThemes = Array.from(monacoThemeByKey.values());
|
|
2029
|
+
const wantsLangs = Array.from(monacoLanguageSet.values());
|
|
2030
|
+
const canLoadTheme = typeof h.loadTheme === "function";
|
|
2031
|
+
const canLoadLanguage = typeof h.loadLanguage === "function";
|
|
2032
|
+
if (canLoadTheme || canLoadLanguage) {
|
|
2033
|
+
if (canLoadTheme) for (const t of themes) {
|
|
2034
|
+
const k = themeKey(t);
|
|
2035
|
+
if (!h.__streamMonacoLoadedThemes) h.__streamMonacoLoadedThemes = /* @__PURE__ */ new Set();
|
|
2036
|
+
const loaded = h.__streamMonacoLoadedThemes;
|
|
2037
|
+
if (loaded.has(k)) continue;
|
|
2038
|
+
await h.loadTheme(t);
|
|
2039
|
+
loaded.add(k);
|
|
2040
|
+
}
|
|
2041
|
+
if (canLoadLanguage) for (const l of languages$1) {
|
|
2042
|
+
if (!h.__streamMonacoLoadedLangs) h.__streamMonacoLoadedLangs = /* @__PURE__ */ new Set();
|
|
2043
|
+
const loaded = h.__streamMonacoLoadedLangs;
|
|
2044
|
+
if (loaded.has(l)) continue;
|
|
2045
|
+
await h.loadLanguage(l);
|
|
2046
|
+
loaded.add(l);
|
|
2047
|
+
}
|
|
2048
|
+
return h;
|
|
2049
|
+
}
|
|
2050
|
+
const p = (0, shiki.createHighlighter)({
|
|
2051
|
+
themes: wantsThemes,
|
|
2052
|
+
langs: wantsLangs
|
|
2053
|
+
}).then((hh) => hh);
|
|
2054
|
+
monacoHighlighterPromise = p;
|
|
2055
|
+
return p;
|
|
2056
|
+
}
|
|
2011
2057
|
/**
|
|
2012
2058
|
* Clear all cached shiki highlighters.
|
|
2013
2059
|
*
|
|
@@ -2082,15 +2128,12 @@ async function getOrCreateHighlighter(themes, languages$1) {
|
|
|
2082
2128
|
async function registerMonacoThemes(themes, languages$1) {
|
|
2083
2129
|
return enqueueRegistration(async () => {
|
|
2084
2130
|
registerMonacoLanguages(languages$1);
|
|
2085
|
-
if (themesRegistered && arraysEqual(themes, currentThemes) && arraysEqual(languages$1, currentLanguages)) {
|
|
2086
|
-
const existing = highlighterCache.get(serializeThemes(themes));
|
|
2087
|
-
return existing ? existing.promise : Promise.resolve(null);
|
|
2088
|
-
}
|
|
2089
2131
|
const p = (async () => {
|
|
2090
|
-
const highlighter = await
|
|
2091
|
-
(
|
|
2092
|
-
|
|
2093
|
-
|
|
2132
|
+
const highlighter = await ensureMonacoHighlighter(themes, languages$1);
|
|
2133
|
+
if (lastPatchedHighlighter !== highlighter) {
|
|
2134
|
+
(0, __shikijs_monaco.shikiToMonaco)(highlighter, monaco_shim_exports);
|
|
2135
|
+
lastPatchedHighlighter = highlighter;
|
|
2136
|
+
}
|
|
2094
2137
|
currentLanguages = languages$1.slice();
|
|
2095
2138
|
return highlighter;
|
|
2096
2139
|
})();
|
|
@@ -2125,6 +2168,9 @@ let RevealStrategy = /* @__PURE__ */ function(RevealStrategy$1) {
|
|
|
2125
2168
|
|
|
2126
2169
|
//#endregion
|
|
2127
2170
|
//#region src/index.ts
|
|
2171
|
+
let globalRequestedThemeName = null;
|
|
2172
|
+
let globalThemeRequestSeq = 0;
|
|
2173
|
+
let globalAppliedThemeName = null;
|
|
2128
2174
|
/**
|
|
2129
2175
|
* useMonaco 组合式函数
|
|
2130
2176
|
*
|
|
@@ -2255,40 +2301,62 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2255
2301
|
const cachedComputedHeight = null;
|
|
2256
2302
|
const appendBuffer = [];
|
|
2257
2303
|
let appendBufferScheduled = false;
|
|
2258
|
-
let lastAppliedTheme = null;
|
|
2259
2304
|
const currentTheme = computed(() => monacoOptions.theme ?? (typeof themes[0] === "string" ? themes[0] : themes[0].name));
|
|
2305
|
+
let requestedThemeName = monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
|
|
2260
2306
|
let themeWatcher = null;
|
|
2261
2307
|
const rafScheduler = createRafScheduler();
|
|
2308
|
+
async function tryLoadAndSetShikiTheme(highlighter, themeName) {
|
|
2309
|
+
if (!highlighter || typeof highlighter.setTheme !== "function") return;
|
|
2310
|
+
try {
|
|
2311
|
+
await highlighter.setTheme(themeName);
|
|
2312
|
+
} catch (err) {
|
|
2313
|
+
const message = (err === null || err === void 0 ? void 0 : err.message) ? String(err.message) : String(err);
|
|
2314
|
+
const lower = message.toLowerCase();
|
|
2315
|
+
const looksLikeMissingThemeError = lower.includes("theme") && lower.includes("not found");
|
|
2316
|
+
if (typeof highlighter.loadTheme === "function" && looksLikeMissingThemeError) {
|
|
2317
|
+
await highlighter.loadTheme(themeName);
|
|
2318
|
+
await highlighter.setTheme(themeName);
|
|
2319
|
+
return;
|
|
2320
|
+
}
|
|
2321
|
+
throw err;
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2262
2324
|
async function setThemeInternal(theme, force = false) {
|
|
2263
2325
|
const themeName = typeof theme === "string" ? theme : theme.name;
|
|
2264
|
-
|
|
2265
|
-
const
|
|
2266
|
-
|
|
2326
|
+
globalThemeRequestSeq += 1;
|
|
2327
|
+
const token = globalThemeRequestSeq;
|
|
2328
|
+
requestedThemeName = themeName;
|
|
2329
|
+
globalRequestedThemeName = themeName;
|
|
2330
|
+
if (!force && themeName === globalAppliedThemeName) return;
|
|
2331
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2332
|
+
await registerMonacoThemes(themes, languages$1).catch(() => void 0);
|
|
2333
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2267
2334
|
const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
|
|
2268
2335
|
if (!availableNames.includes(themeName)) try {
|
|
2269
2336
|
const extended = availableNames.concat(themeName);
|
|
2270
|
-
const maybeHighlighter = await
|
|
2271
|
-
|
|
2272
|
-
await maybeHighlighter.setTheme(themeName);
|
|
2273
|
-
} catch {}
|
|
2337
|
+
const maybeHighlighter = await registerMonacoThemes(extended, languages$1);
|
|
2338
|
+
await tryLoadAndSetShikiTheme(maybeHighlighter, themeName).catch(() => void 0);
|
|
2274
2339
|
} catch {
|
|
2275
2340
|
console.warn(`Theme "${themeName}" is not registered and automatic registration failed. Available themes: ${availableNames.join(", ")}`);
|
|
2276
2341
|
return;
|
|
2277
2342
|
}
|
|
2343
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2278
2344
|
try {
|
|
2279
2345
|
monaco_shim_exports.editor.setTheme(themeName);
|
|
2280
|
-
|
|
2346
|
+
globalAppliedThemeName = themeName;
|
|
2281
2347
|
} catch {
|
|
2282
2348
|
try {
|
|
2283
2349
|
const maybeHighlighter = await registerMonacoThemes(themes, languages$1);
|
|
2350
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2284
2351
|
monaco_shim_exports.editor.setTheme(themeName);
|
|
2285
|
-
|
|
2286
|
-
|
|
2352
|
+
globalAppliedThemeName = themeName;
|
|
2353
|
+
await tryLoadAndSetShikiTheme(maybeHighlighter, themeName).catch(() => void 0);
|
|
2287
2354
|
} catch (err2) {
|
|
2288
2355
|
console.warn(`Failed to set theme "${themeName}":`, err2);
|
|
2289
2356
|
return;
|
|
2290
2357
|
}
|
|
2291
2358
|
}
|
|
2359
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2292
2360
|
try {
|
|
2293
2361
|
if (typeof monacoOptions.onThemeChange === "function") await monacoOptions.onThemeChange(themeName);
|
|
2294
2362
|
} catch (err) {
|
|
@@ -2298,8 +2366,7 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2298
2366
|
async function ensureThemeRegistered(themeName) {
|
|
2299
2367
|
const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
|
|
2300
2368
|
const list = availableNames.includes(themeName) ? themes : themes.concat(themeName);
|
|
2301
|
-
|
|
2302
|
-
if (p) await p;
|
|
2369
|
+
await registerMonacoThemes(list, languages$1);
|
|
2303
2370
|
}
|
|
2304
2371
|
function hasVerticalScrollbar() {
|
|
2305
2372
|
if (!editorView) return false;
|
|
@@ -2341,11 +2408,10 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2341
2408
|
const ds = monacoOptions.onBeforeCreate(monaco_shim_exports);
|
|
2342
2409
|
if (ds) disposals.push(...ds);
|
|
2343
2410
|
}
|
|
2344
|
-
const initialThemeName = monacoOptions.theme ?? currentTheme.value;
|
|
2411
|
+
const initialThemeName = requestedThemeName ?? monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
|
|
2345
2412
|
await ensureThemeRegistered(initialThemeName);
|
|
2346
2413
|
editorMgr = new EditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, monacoOptions.revealDebounceMs);
|
|
2347
2414
|
editorView = await editorMgr.createEditor(container, code, language, initialThemeName);
|
|
2348
|
-
lastAppliedTheme = initialThemeName;
|
|
2349
2415
|
if (pendingUpdate && editorMgr) {
|
|
2350
2416
|
const { code: queuedCode, lang: queuedLang } = pendingUpdate;
|
|
2351
2417
|
pendingUpdate = null;
|
|
@@ -2373,11 +2439,10 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2373
2439
|
const ds = monacoOptions.onBeforeCreate(monaco_shim_exports);
|
|
2374
2440
|
if (ds) disposals.push(...ds);
|
|
2375
2441
|
}
|
|
2376
|
-
const initialThemeName = monacoOptions.theme ?? currentTheme.value;
|
|
2442
|
+
const initialThemeName = requestedThemeName ?? monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
|
|
2377
2443
|
await ensureThemeRegistered(initialThemeName);
|
|
2378
2444
|
try {
|
|
2379
2445
|
monaco_shim_exports.editor.setTheme(initialThemeName);
|
|
2380
|
-
lastAppliedTheme = initialThemeName;
|
|
2381
2446
|
} catch {}
|
|
2382
2447
|
diffMgr = new DiffEditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, diffAutoScroll, monacoOptions.revealDebounceMs);
|
|
2383
2448
|
diffEditorView = await diffMgr.createDiffEditor(container, originalCode, modifiedCode, language, initialThemeName);
|
|
@@ -2668,7 +2733,7 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2668
2733
|
} else console.warn(`Language "${language}" is not registered. Available languages: ${languages$1.join(", ")}`);
|
|
2669
2734
|
},
|
|
2670
2735
|
getCurrentTheme() {
|
|
2671
|
-
return currentTheme.value;
|
|
2736
|
+
return globalAppliedThemeName ?? requestedThemeName ?? globalRequestedThemeName ?? currentTheme.value;
|
|
2672
2737
|
},
|
|
2673
2738
|
getEditor() {
|
|
2674
2739
|
return monaco_shim_exports.editor;
|
package/dist/index.js
CHANGED
|
@@ -1965,9 +1965,7 @@ function arraysEqual(a, b) {
|
|
|
1965
1965
|
|
|
1966
1966
|
//#endregion
|
|
1967
1967
|
//#region src/utils/registerMonacoThemes.ts
|
|
1968
|
-
let themesRegistered = false;
|
|
1969
1968
|
let languagesRegistered = false;
|
|
1970
|
-
let currentThemes = [];
|
|
1971
1969
|
let currentLanguages = [];
|
|
1972
1970
|
let themeRegisterPromise = null;
|
|
1973
1971
|
let registrationQueue = Promise.resolve();
|
|
@@ -1980,6 +1978,54 @@ function setThemeRegisterPromise(p) {
|
|
|
1980
1978
|
return themeRegisterPromise = p;
|
|
1981
1979
|
}
|
|
1982
1980
|
const highlighterCache = /* @__PURE__ */ new Map();
|
|
1981
|
+
let monacoHighlighterPromise = null;
|
|
1982
|
+
let lastPatchedHighlighter = null;
|
|
1983
|
+
const monacoThemeByKey = /* @__PURE__ */ new Map();
|
|
1984
|
+
const monacoLanguageSet = /* @__PURE__ */ new Set();
|
|
1985
|
+
function themeKey(t) {
|
|
1986
|
+
return typeof t === "string" ? t : t.name ?? JSON.stringify(t);
|
|
1987
|
+
}
|
|
1988
|
+
async function ensureMonacoHighlighter(themes, languages$1) {
|
|
1989
|
+
for (const t of themes) monacoThemeByKey.set(themeKey(t), t);
|
|
1990
|
+
for (const l of languages$1) monacoLanguageSet.add(l);
|
|
1991
|
+
if (!monacoHighlighterPromise) {
|
|
1992
|
+
const initialThemes = Array.from(monacoThemeByKey.values());
|
|
1993
|
+
const initialLangs = Array.from(monacoLanguageSet.values());
|
|
1994
|
+
monacoHighlighterPromise = createHighlighter({
|
|
1995
|
+
themes: initialThemes,
|
|
1996
|
+
langs: initialLangs
|
|
1997
|
+
}).then((h$1) => h$1);
|
|
1998
|
+
}
|
|
1999
|
+
const h = await monacoHighlighterPromise;
|
|
2000
|
+
const wantsThemes = Array.from(monacoThemeByKey.values());
|
|
2001
|
+
const wantsLangs = Array.from(monacoLanguageSet.values());
|
|
2002
|
+
const canLoadTheme = typeof h.loadTheme === "function";
|
|
2003
|
+
const canLoadLanguage = typeof h.loadLanguage === "function";
|
|
2004
|
+
if (canLoadTheme || canLoadLanguage) {
|
|
2005
|
+
if (canLoadTheme) for (const t of themes) {
|
|
2006
|
+
const k = themeKey(t);
|
|
2007
|
+
if (!h.__streamMonacoLoadedThemes) h.__streamMonacoLoadedThemes = /* @__PURE__ */ new Set();
|
|
2008
|
+
const loaded = h.__streamMonacoLoadedThemes;
|
|
2009
|
+
if (loaded.has(k)) continue;
|
|
2010
|
+
await h.loadTheme(t);
|
|
2011
|
+
loaded.add(k);
|
|
2012
|
+
}
|
|
2013
|
+
if (canLoadLanguage) for (const l of languages$1) {
|
|
2014
|
+
if (!h.__streamMonacoLoadedLangs) h.__streamMonacoLoadedLangs = /* @__PURE__ */ new Set();
|
|
2015
|
+
const loaded = h.__streamMonacoLoadedLangs;
|
|
2016
|
+
if (loaded.has(l)) continue;
|
|
2017
|
+
await h.loadLanguage(l);
|
|
2018
|
+
loaded.add(l);
|
|
2019
|
+
}
|
|
2020
|
+
return h;
|
|
2021
|
+
}
|
|
2022
|
+
const p = createHighlighter({
|
|
2023
|
+
themes: wantsThemes,
|
|
2024
|
+
langs: wantsLangs
|
|
2025
|
+
}).then((hh) => hh);
|
|
2026
|
+
monacoHighlighterPromise = p;
|
|
2027
|
+
return p;
|
|
2028
|
+
}
|
|
1983
2029
|
/**
|
|
1984
2030
|
* Clear all cached shiki highlighters.
|
|
1985
2031
|
*
|
|
@@ -2054,15 +2100,12 @@ async function getOrCreateHighlighter(themes, languages$1) {
|
|
|
2054
2100
|
async function registerMonacoThemes(themes, languages$1) {
|
|
2055
2101
|
return enqueueRegistration(async () => {
|
|
2056
2102
|
registerMonacoLanguages(languages$1);
|
|
2057
|
-
if (themesRegistered && arraysEqual(themes, currentThemes) && arraysEqual(languages$1, currentLanguages)) {
|
|
2058
|
-
const existing = highlighterCache.get(serializeThemes(themes));
|
|
2059
|
-
return existing ? existing.promise : Promise.resolve(null);
|
|
2060
|
-
}
|
|
2061
2103
|
const p = (async () => {
|
|
2062
|
-
const highlighter = await
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2104
|
+
const highlighter = await ensureMonacoHighlighter(themes, languages$1);
|
|
2105
|
+
if (lastPatchedHighlighter !== highlighter) {
|
|
2106
|
+
shikiToMonaco(highlighter, monaco_shim_exports);
|
|
2107
|
+
lastPatchedHighlighter = highlighter;
|
|
2108
|
+
}
|
|
2066
2109
|
currentLanguages = languages$1.slice();
|
|
2067
2110
|
return highlighter;
|
|
2068
2111
|
})();
|
|
@@ -2097,6 +2140,9 @@ let RevealStrategy = /* @__PURE__ */ function(RevealStrategy$1) {
|
|
|
2097
2140
|
|
|
2098
2141
|
//#endregion
|
|
2099
2142
|
//#region src/index.ts
|
|
2143
|
+
let globalRequestedThemeName = null;
|
|
2144
|
+
let globalThemeRequestSeq = 0;
|
|
2145
|
+
let globalAppliedThemeName = null;
|
|
2100
2146
|
/**
|
|
2101
2147
|
* useMonaco 组合式函数
|
|
2102
2148
|
*
|
|
@@ -2227,40 +2273,62 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2227
2273
|
const cachedComputedHeight = null;
|
|
2228
2274
|
const appendBuffer = [];
|
|
2229
2275
|
let appendBufferScheduled = false;
|
|
2230
|
-
let lastAppliedTheme = null;
|
|
2231
2276
|
const currentTheme = computed$1(() => monacoOptions.theme ?? (typeof themes[0] === "string" ? themes[0] : themes[0].name));
|
|
2277
|
+
let requestedThemeName = monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
|
|
2232
2278
|
let themeWatcher = null;
|
|
2233
2279
|
const rafScheduler = createRafScheduler();
|
|
2280
|
+
async function tryLoadAndSetShikiTheme(highlighter, themeName) {
|
|
2281
|
+
if (!highlighter || typeof highlighter.setTheme !== "function") return;
|
|
2282
|
+
try {
|
|
2283
|
+
await highlighter.setTheme(themeName);
|
|
2284
|
+
} catch (err) {
|
|
2285
|
+
const message = (err === null || err === void 0 ? void 0 : err.message) ? String(err.message) : String(err);
|
|
2286
|
+
const lower = message.toLowerCase();
|
|
2287
|
+
const looksLikeMissingThemeError = lower.includes("theme") && lower.includes("not found");
|
|
2288
|
+
if (typeof highlighter.loadTheme === "function" && looksLikeMissingThemeError) {
|
|
2289
|
+
await highlighter.loadTheme(themeName);
|
|
2290
|
+
await highlighter.setTheme(themeName);
|
|
2291
|
+
return;
|
|
2292
|
+
}
|
|
2293
|
+
throw err;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2234
2296
|
async function setThemeInternal(theme, force = false) {
|
|
2235
2297
|
const themeName = typeof theme === "string" ? theme : theme.name;
|
|
2236
|
-
|
|
2237
|
-
const
|
|
2238
|
-
|
|
2298
|
+
globalThemeRequestSeq += 1;
|
|
2299
|
+
const token = globalThemeRequestSeq;
|
|
2300
|
+
requestedThemeName = themeName;
|
|
2301
|
+
globalRequestedThemeName = themeName;
|
|
2302
|
+
if (!force && themeName === globalAppliedThemeName) return;
|
|
2303
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2304
|
+
await registerMonacoThemes(themes, languages$1).catch(() => void 0);
|
|
2305
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2239
2306
|
const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
|
|
2240
2307
|
if (!availableNames.includes(themeName)) try {
|
|
2241
2308
|
const extended = availableNames.concat(themeName);
|
|
2242
|
-
const maybeHighlighter = await
|
|
2243
|
-
|
|
2244
|
-
await maybeHighlighter.setTheme(themeName);
|
|
2245
|
-
} catch {}
|
|
2309
|
+
const maybeHighlighter = await registerMonacoThemes(extended, languages$1);
|
|
2310
|
+
await tryLoadAndSetShikiTheme(maybeHighlighter, themeName).catch(() => void 0);
|
|
2246
2311
|
} catch {
|
|
2247
2312
|
console.warn(`Theme "${themeName}" is not registered and automatic registration failed. Available themes: ${availableNames.join(", ")}`);
|
|
2248
2313
|
return;
|
|
2249
2314
|
}
|
|
2315
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2250
2316
|
try {
|
|
2251
2317
|
monaco_shim_exports.editor.setTheme(themeName);
|
|
2252
|
-
|
|
2318
|
+
globalAppliedThemeName = themeName;
|
|
2253
2319
|
} catch {
|
|
2254
2320
|
try {
|
|
2255
2321
|
const maybeHighlighter = await registerMonacoThemes(themes, languages$1);
|
|
2322
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2256
2323
|
monaco_shim_exports.editor.setTheme(themeName);
|
|
2257
|
-
|
|
2258
|
-
|
|
2324
|
+
globalAppliedThemeName = themeName;
|
|
2325
|
+
await tryLoadAndSetShikiTheme(maybeHighlighter, themeName).catch(() => void 0);
|
|
2259
2326
|
} catch (err2) {
|
|
2260
2327
|
console.warn(`Failed to set theme "${themeName}":`, err2);
|
|
2261
2328
|
return;
|
|
2262
2329
|
}
|
|
2263
2330
|
}
|
|
2331
|
+
if (token !== globalThemeRequestSeq) return;
|
|
2264
2332
|
try {
|
|
2265
2333
|
if (typeof monacoOptions.onThemeChange === "function") await monacoOptions.onThemeChange(themeName);
|
|
2266
2334
|
} catch (err) {
|
|
@@ -2270,8 +2338,7 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2270
2338
|
async function ensureThemeRegistered(themeName) {
|
|
2271
2339
|
const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
|
|
2272
2340
|
const list = availableNames.includes(themeName) ? themes : themes.concat(themeName);
|
|
2273
|
-
|
|
2274
|
-
if (p) await p;
|
|
2341
|
+
await registerMonacoThemes(list, languages$1);
|
|
2275
2342
|
}
|
|
2276
2343
|
function hasVerticalScrollbar() {
|
|
2277
2344
|
if (!editorView) return false;
|
|
@@ -2313,11 +2380,10 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2313
2380
|
const ds = monacoOptions.onBeforeCreate(monaco_shim_exports);
|
|
2314
2381
|
if (ds) disposals.push(...ds);
|
|
2315
2382
|
}
|
|
2316
|
-
const initialThemeName = monacoOptions.theme ?? currentTheme.value;
|
|
2383
|
+
const initialThemeName = requestedThemeName ?? monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
|
|
2317
2384
|
await ensureThemeRegistered(initialThemeName);
|
|
2318
2385
|
editorMgr = new EditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, monacoOptions.revealDebounceMs);
|
|
2319
2386
|
editorView = await editorMgr.createEditor(container, code, language, initialThemeName);
|
|
2320
|
-
lastAppliedTheme = initialThemeName;
|
|
2321
2387
|
if (pendingUpdate && editorMgr) {
|
|
2322
2388
|
const { code: queuedCode, lang: queuedLang } = pendingUpdate;
|
|
2323
2389
|
pendingUpdate = null;
|
|
@@ -2345,11 +2411,10 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2345
2411
|
const ds = monacoOptions.onBeforeCreate(monaco_shim_exports);
|
|
2346
2412
|
if (ds) disposals.push(...ds);
|
|
2347
2413
|
}
|
|
2348
|
-
const initialThemeName = monacoOptions.theme ?? currentTheme.value;
|
|
2414
|
+
const initialThemeName = requestedThemeName ?? monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
|
|
2349
2415
|
await ensureThemeRegistered(initialThemeName);
|
|
2350
2416
|
try {
|
|
2351
2417
|
monaco_shim_exports.editor.setTheme(initialThemeName);
|
|
2352
|
-
lastAppliedTheme = initialThemeName;
|
|
2353
2418
|
} catch {}
|
|
2354
2419
|
diffMgr = new DiffEditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, diffAutoScroll, monacoOptions.revealDebounceMs);
|
|
2355
2420
|
diffEditorView = await diffMgr.createDiffEditor(container, originalCode, modifiedCode, language, initialThemeName);
|
|
@@ -2640,7 +2705,7 @@ function useMonaco(monacoOptions = {}) {
|
|
|
2640
2705
|
} else console.warn(`Language "${language}" is not registered. Available languages: ${languages$1.join(", ")}`);
|
|
2641
2706
|
},
|
|
2642
2707
|
getCurrentTheme() {
|
|
2643
|
-
return currentTheme.value;
|
|
2708
|
+
return globalAppliedThemeName ?? requestedThemeName ?? globalRequestedThemeName ?? currentTheme.value;
|
|
2644
2709
|
},
|
|
2645
2710
|
getEditor() {
|
|
2646
2711
|
return monaco_shim_exports.editor;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stream-monaco",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.13",
|
|
5
5
|
"description": "A framework-agnostic library for integrating Monaco Editor with Shiki highlighting, optimized for streaming updates.",
|
|
6
6
|
"author": "Simon He",
|
|
7
7
|
"license": "MIT",
|