stream-monaco 0.0.9 → 0.0.12

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
@@ -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: If you only use Monaco and pass all `themes` to `createEditor`, typically just call `monaco.editor.setTheme(themeName)`.
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,15 +1993,67 @@ 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;
1999
+ let registrationQueue = Promise.resolve();
2000
+ function enqueueRegistration(task) {
2001
+ const next = registrationQueue.then(task, task);
2002
+ registrationQueue = next.then(() => void 0, () => void 0);
2003
+ return next;
2004
+ }
2001
2005
  function setThemeRegisterPromise(p) {
2002
2006
  return themeRegisterPromise = p;
2003
2007
  }
2004
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
+ }
2005
2057
  /**
2006
2058
  * Clear all cached shiki highlighters.
2007
2059
  *
@@ -2074,27 +2126,26 @@ async function getOrCreateHighlighter(themes, languages$1) {
2074
2126
  * standalone renderer to use the new theme without recreating everything.
2075
2127
  */
2076
2128
  async function registerMonacoThemes(themes, languages$1) {
2077
- registerMonacoLanguages(languages$1);
2078
- if (themesRegistered && arraysEqual(themes, currentThemes) && arraysEqual(languages$1, currentLanguages)) {
2079
- const existing = highlighterCache.get(serializeThemes(themes));
2080
- return existing ? existing.promise : Promise.resolve(null);
2081
- }
2082
- const p = (async () => {
2083
- const highlighter = await getOrCreateHighlighter(themes, languages$1);
2084
- (0, __shikijs_monaco.shikiToMonaco)(highlighter, monaco_shim_exports);
2085
- themesRegistered = true;
2086
- currentThemes = themes.slice();
2087
- currentLanguages = languages$1.slice();
2088
- return highlighter;
2089
- })();
2090
- setThemeRegisterPromise(p);
2091
- try {
2092
- const res = await p;
2093
- return res;
2094
- } catch (e) {
2095
- setThemeRegisterPromise(null);
2096
- throw e;
2097
- }
2129
+ return enqueueRegistration(async () => {
2130
+ registerMonacoLanguages(languages$1);
2131
+ const p = (async () => {
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
+ }
2137
+ currentLanguages = languages$1.slice();
2138
+ return highlighter;
2139
+ })();
2140
+ setThemeRegisterPromise(p);
2141
+ try {
2142
+ const res = await p;
2143
+ return res;
2144
+ } catch (e) {
2145
+ setThemeRegisterPromise(null);
2146
+ throw e;
2147
+ }
2148
+ });
2098
2149
  }
2099
2150
  function registerMonacoLanguages(languages$1) {
2100
2151
  if (languagesRegistered && arraysEqual(languages$1, currentLanguages)) return;
@@ -2117,6 +2168,9 @@ let RevealStrategy = /* @__PURE__ */ function(RevealStrategy$1) {
2117
2168
 
2118
2169
  //#endregion
2119
2170
  //#region src/index.ts
2171
+ let globalRequestedThemeName = null;
2172
+ let globalThemeRequestSeq = 0;
2173
+ let globalAppliedThemeName = null;
2120
2174
  /**
2121
2175
  * useMonaco 组合式函数
2122
2176
  *
@@ -2247,40 +2301,64 @@ function useMonaco(monacoOptions = {}) {
2247
2301
  const cachedComputedHeight = null;
2248
2302
  const appendBuffer = [];
2249
2303
  let appendBufferScheduled = false;
2250
- let lastAppliedTheme = null;
2251
2304
  const currentTheme = computed(() => monacoOptions.theme ?? (typeof themes[0] === "string" ? themes[0] : themes[0].name));
2305
+ let requestedThemeName = monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
2252
2306
  let themeWatcher = null;
2253
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
+ }
2254
2324
  async function setThemeInternal(theme, force = false) {
2255
2325
  const themeName = typeof theme === "string" ? theme : theme.name;
2256
- if (!force && themeName === lastAppliedTheme) return;
2257
- const _p = setThemeRegisterPromise(registerMonacoThemes(themes, languages$1));
2258
- if (_p) await _p.catch(() => void 0);
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;
2259
2334
  const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
2260
2335
  if (!availableNames.includes(themeName)) try {
2261
2336
  const extended = availableNames.concat(themeName);
2262
- const maybeHighlighter = await setThemeRegisterPromise(registerMonacoThemes(extended, languages$1));
2263
- if (maybeHighlighter && typeof maybeHighlighter.setTheme === "function") try {
2264
- await maybeHighlighter.setTheme(themeName);
2265
- } catch {}
2337
+ const maybeHighlighter = await registerMonacoThemes(extended, languages$1);
2338
+ await tryLoadAndSetShikiTheme(maybeHighlighter, themeName).catch(() => void 0);
2266
2339
  } catch {
2267
2340
  console.warn(`Theme "${themeName}" is not registered and automatic registration failed. Available themes: ${availableNames.join(", ")}`);
2268
2341
  return;
2269
2342
  }
2343
+ if (token !== globalThemeRequestSeq) return;
2270
2344
  try {
2271
2345
  monaco_shim_exports.editor.setTheme(themeName);
2272
2346
  lastAppliedTheme = themeName;
2347
+ globalAppliedThemeName = themeName;
2273
2348
  } catch {
2274
2349
  try {
2275
2350
  const maybeHighlighter = await registerMonacoThemes(themes, languages$1);
2351
+ if (token !== globalThemeRequestSeq) return;
2276
2352
  monaco_shim_exports.editor.setTheme(themeName);
2277
2353
  lastAppliedTheme = themeName;
2278
- if (maybeHighlighter && typeof maybeHighlighter.setTheme === "function") await maybeHighlighter.setTheme(themeName).catch(() => void 0);
2354
+ globalAppliedThemeName = themeName;
2355
+ await tryLoadAndSetShikiTheme(maybeHighlighter, themeName).catch(() => void 0);
2279
2356
  } catch (err2) {
2280
2357
  console.warn(`Failed to set theme "${themeName}":`, err2);
2281
2358
  return;
2282
2359
  }
2283
2360
  }
2361
+ if (token !== globalThemeRequestSeq) return;
2284
2362
  try {
2285
2363
  if (typeof monacoOptions.onThemeChange === "function") await monacoOptions.onThemeChange(themeName);
2286
2364
  } catch (err) {
@@ -2290,8 +2368,7 @@ function useMonaco(monacoOptions = {}) {
2290
2368
  async function ensureThemeRegistered(themeName) {
2291
2369
  const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
2292
2370
  const list = availableNames.includes(themeName) ? themes : themes.concat(themeName);
2293
- const p = setThemeRegisterPromise(registerMonacoThemes(list, languages$1));
2294
- if (p) await p;
2371
+ await registerMonacoThemes(list, languages$1);
2295
2372
  }
2296
2373
  function hasVerticalScrollbar() {
2297
2374
  if (!editorView) return false;
@@ -2333,7 +2410,7 @@ function useMonaco(monacoOptions = {}) {
2333
2410
  const ds = monacoOptions.onBeforeCreate(monaco_shim_exports);
2334
2411
  if (ds) disposals.push(...ds);
2335
2412
  }
2336
- const initialThemeName = monacoOptions.theme ?? currentTheme.value;
2413
+ const initialThemeName = requestedThemeName ?? monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
2337
2414
  await ensureThemeRegistered(initialThemeName);
2338
2415
  editorMgr = new EditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, monacoOptions.revealDebounceMs);
2339
2416
  editorView = await editorMgr.createEditor(container, code, language, initialThemeName);
@@ -2365,7 +2442,7 @@ function useMonaco(monacoOptions = {}) {
2365
2442
  const ds = monacoOptions.onBeforeCreate(monaco_shim_exports);
2366
2443
  if (ds) disposals.push(...ds);
2367
2444
  }
2368
- const initialThemeName = monacoOptions.theme ?? currentTheme.value;
2445
+ const initialThemeName = requestedThemeName ?? monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
2369
2446
  await ensureThemeRegistered(initialThemeName);
2370
2447
  try {
2371
2448
  monaco_shim_exports.editor.setTheme(initialThemeName);
@@ -2660,7 +2737,7 @@ function useMonaco(monacoOptions = {}) {
2660
2737
  } else console.warn(`Language "${language}" is not registered. Available languages: ${languages$1.join(", ")}`);
2661
2738
  },
2662
2739
  getCurrentTheme() {
2663
- return currentTheme.value;
2740
+ return globalAppliedThemeName ?? requestedThemeName ?? globalRequestedThemeName ?? currentTheme.value;
2664
2741
  },
2665
2742
  getEditor() {
2666
2743
  return monaco_shim_exports.editor;
package/dist/index.js CHANGED
@@ -1965,15 +1965,67 @@ 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;
1971
+ let registrationQueue = Promise.resolve();
1972
+ function enqueueRegistration(task) {
1973
+ const next = registrationQueue.then(task, task);
1974
+ registrationQueue = next.then(() => void 0, () => void 0);
1975
+ return next;
1976
+ }
1973
1977
  function setThemeRegisterPromise(p) {
1974
1978
  return themeRegisterPromise = p;
1975
1979
  }
1976
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
+ }
1977
2029
  /**
1978
2030
  * Clear all cached shiki highlighters.
1979
2031
  *
@@ -2046,27 +2098,26 @@ async function getOrCreateHighlighter(themes, languages$1) {
2046
2098
  * standalone renderer to use the new theme without recreating everything.
2047
2099
  */
2048
2100
  async function registerMonacoThemes(themes, languages$1) {
2049
- registerMonacoLanguages(languages$1);
2050
- if (themesRegistered && arraysEqual(themes, currentThemes) && arraysEqual(languages$1, currentLanguages)) {
2051
- const existing = highlighterCache.get(serializeThemes(themes));
2052
- return existing ? existing.promise : Promise.resolve(null);
2053
- }
2054
- const p = (async () => {
2055
- const highlighter = await getOrCreateHighlighter(themes, languages$1);
2056
- shikiToMonaco(highlighter, monaco_shim_exports);
2057
- themesRegistered = true;
2058
- currentThemes = themes.slice();
2059
- currentLanguages = languages$1.slice();
2060
- return highlighter;
2061
- })();
2062
- setThemeRegisterPromise(p);
2063
- try {
2064
- const res = await p;
2065
- return res;
2066
- } catch (e) {
2067
- setThemeRegisterPromise(null);
2068
- throw e;
2069
- }
2101
+ return enqueueRegistration(async () => {
2102
+ registerMonacoLanguages(languages$1);
2103
+ const p = (async () => {
2104
+ const highlighter = await ensureMonacoHighlighter(themes, languages$1);
2105
+ if (lastPatchedHighlighter !== highlighter) {
2106
+ shikiToMonaco(highlighter, monaco_shim_exports);
2107
+ lastPatchedHighlighter = highlighter;
2108
+ }
2109
+ currentLanguages = languages$1.slice();
2110
+ return highlighter;
2111
+ })();
2112
+ setThemeRegisterPromise(p);
2113
+ try {
2114
+ const res = await p;
2115
+ return res;
2116
+ } catch (e) {
2117
+ setThemeRegisterPromise(null);
2118
+ throw e;
2119
+ }
2120
+ });
2070
2121
  }
2071
2122
  function registerMonacoLanguages(languages$1) {
2072
2123
  if (languagesRegistered && arraysEqual(languages$1, currentLanguages)) return;
@@ -2089,6 +2140,9 @@ let RevealStrategy = /* @__PURE__ */ function(RevealStrategy$1) {
2089
2140
 
2090
2141
  //#endregion
2091
2142
  //#region src/index.ts
2143
+ let globalRequestedThemeName = null;
2144
+ let globalThemeRequestSeq = 0;
2145
+ let globalAppliedThemeName = null;
2092
2146
  /**
2093
2147
  * useMonaco 组合式函数
2094
2148
  *
@@ -2219,40 +2273,64 @@ function useMonaco(monacoOptions = {}) {
2219
2273
  const cachedComputedHeight = null;
2220
2274
  const appendBuffer = [];
2221
2275
  let appendBufferScheduled = false;
2222
- let lastAppliedTheme = null;
2223
2276
  const currentTheme = computed$1(() => monacoOptions.theme ?? (typeof themes[0] === "string" ? themes[0] : themes[0].name));
2277
+ let requestedThemeName = monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
2224
2278
  let themeWatcher = null;
2225
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
+ }
2226
2296
  async function setThemeInternal(theme, force = false) {
2227
2297
  const themeName = typeof theme === "string" ? theme : theme.name;
2228
- if (!force && themeName === lastAppliedTheme) return;
2229
- const _p = setThemeRegisterPromise(registerMonacoThemes(themes, languages$1));
2230
- if (_p) await _p.catch(() => void 0);
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;
2231
2306
  const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
2232
2307
  if (!availableNames.includes(themeName)) try {
2233
2308
  const extended = availableNames.concat(themeName);
2234
- const maybeHighlighter = await setThemeRegisterPromise(registerMonacoThemes(extended, languages$1));
2235
- if (maybeHighlighter && typeof maybeHighlighter.setTheme === "function") try {
2236
- await maybeHighlighter.setTheme(themeName);
2237
- } catch {}
2309
+ const maybeHighlighter = await registerMonacoThemes(extended, languages$1);
2310
+ await tryLoadAndSetShikiTheme(maybeHighlighter, themeName).catch(() => void 0);
2238
2311
  } catch {
2239
2312
  console.warn(`Theme "${themeName}" is not registered and automatic registration failed. Available themes: ${availableNames.join(", ")}`);
2240
2313
  return;
2241
2314
  }
2315
+ if (token !== globalThemeRequestSeq) return;
2242
2316
  try {
2243
2317
  monaco_shim_exports.editor.setTheme(themeName);
2244
2318
  lastAppliedTheme = themeName;
2319
+ globalAppliedThemeName = themeName;
2245
2320
  } catch {
2246
2321
  try {
2247
2322
  const maybeHighlighter = await registerMonacoThemes(themes, languages$1);
2323
+ if (token !== globalThemeRequestSeq) return;
2248
2324
  monaco_shim_exports.editor.setTheme(themeName);
2249
2325
  lastAppliedTheme = themeName;
2250
- if (maybeHighlighter && typeof maybeHighlighter.setTheme === "function") await maybeHighlighter.setTheme(themeName).catch(() => void 0);
2326
+ globalAppliedThemeName = themeName;
2327
+ await tryLoadAndSetShikiTheme(maybeHighlighter, themeName).catch(() => void 0);
2251
2328
  } catch (err2) {
2252
2329
  console.warn(`Failed to set theme "${themeName}":`, err2);
2253
2330
  return;
2254
2331
  }
2255
2332
  }
2333
+ if (token !== globalThemeRequestSeq) return;
2256
2334
  try {
2257
2335
  if (typeof monacoOptions.onThemeChange === "function") await monacoOptions.onThemeChange(themeName);
2258
2336
  } catch (err) {
@@ -2262,8 +2340,7 @@ function useMonaco(monacoOptions = {}) {
2262
2340
  async function ensureThemeRegistered(themeName) {
2263
2341
  const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
2264
2342
  const list = availableNames.includes(themeName) ? themes : themes.concat(themeName);
2265
- const p = setThemeRegisterPromise(registerMonacoThemes(list, languages$1));
2266
- if (p) await p;
2343
+ await registerMonacoThemes(list, languages$1);
2267
2344
  }
2268
2345
  function hasVerticalScrollbar() {
2269
2346
  if (!editorView) return false;
@@ -2305,7 +2382,7 @@ function useMonaco(monacoOptions = {}) {
2305
2382
  const ds = monacoOptions.onBeforeCreate(monaco_shim_exports);
2306
2383
  if (ds) disposals.push(...ds);
2307
2384
  }
2308
- const initialThemeName = monacoOptions.theme ?? currentTheme.value;
2385
+ const initialThemeName = requestedThemeName ?? monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
2309
2386
  await ensureThemeRegistered(initialThemeName);
2310
2387
  editorMgr = new EditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, monacoOptions.revealDebounceMs);
2311
2388
  editorView = await editorMgr.createEditor(container, code, language, initialThemeName);
@@ -2337,7 +2414,7 @@ function useMonaco(monacoOptions = {}) {
2337
2414
  const ds = monacoOptions.onBeforeCreate(monaco_shim_exports);
2338
2415
  if (ds) disposals.push(...ds);
2339
2416
  }
2340
- const initialThemeName = monacoOptions.theme ?? currentTheme.value;
2417
+ const initialThemeName = requestedThemeName ?? monacoOptions.theme ?? globalRequestedThemeName ?? currentTheme.value;
2341
2418
  await ensureThemeRegistered(initialThemeName);
2342
2419
  try {
2343
2420
  monaco_shim_exports.editor.setTheme(initialThemeName);
@@ -2632,7 +2709,7 @@ function useMonaco(monacoOptions = {}) {
2632
2709
  } else console.warn(`Language "${language}" is not registered. Available languages: ${languages$1.join(", ")}`);
2633
2710
  },
2634
2711
  getCurrentTheme() {
2635
- return currentTheme.value;
2712
+ return globalAppliedThemeName ?? requestedThemeName ?? globalRequestedThemeName ?? currentTheme.value;
2636
2713
  },
2637
2714
  getEditor() {
2638
2715
  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.9",
4
+ "version": "0.0.12",
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",