@coldsmirk/inkstone-core 0.28.1 → 0.30.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
@@ -10,7 +10,8 @@ Part of [inkstone](https://github.com/coldsmirk/inkstone). The editor layers ([`
10
10
  - **`configureHighlighter(config)`** — extend or replace the default grammar / theme set, and choose the regex engine, once, before any editor mounts. `DEFAULT_HIGHLIGHTER_LANGS` is exported so extension is additive. `engine` takes the engine itself, a promise of one, or a factory called once when the highlighter is first built — configuration stays synchronous while the engine may be async to make: the strict JavaScript engine by default, `createJavaScriptRegexEngine({ forgiving: true })` for grammars the strict one refuses, or `onigurumaEngine`.
11
11
  - **`onigurumaEngine`** — the Oniguruma engine on its WASM, inlined into a chunk of your own bundle (about 600 KB, nothing fetched from anywhere else) and instantiated once, in about 20 ms. Which engine: the JavaScript one translates each grammar's patterns into JavaScript at the first tokenization, on the main thread, and pays for it on whole files — a TypeScript file's first sixty lines cost it about 170 ms, against Oniguruma's 20. Colouring fenced snippets, keep the default; reading whole files in an editor (`@coldsmirk/inkstone-monaco`'s Shiki bridge, `<MonacoEditor>`), pass `onigurumaEngine` as the factory. `onigurumaEngine(wasm)` takes the WASM from elsewhere in any form Shiki's `createOnigurumaEngine` accepts, such as a `fetch("/onig.wasm")`.
12
12
  - **`shikiThemeId(dark)`** plus the `INKSTONE_LIGHT_THEME` / `INKSTONE_DARK_THEME` constants — the theme names to pass wherever a Shiki theme id is expected.
13
- - **`configureEditorSurface(surfaces)`** — re-light every color the editors paint that is not syntax, in your design language, once, before any editor mounts. Per scheme, CSS color literals for the editor (`background` — content, gutter and the fields of its chrome — `lineHighlight`, `lineNumber`, `lineNumberActive`, `cursor`, `selection`, `scrollbar`), its floating chrome — completion, hover, parameter hints, the find widget and search panels, the context menu — (`widget`, `widgetBorder`, `widgetSelection`, `widgetForeground`, `widgetForegroundMuted`), the `accent` that rings a focused field and marks what a completion matched, and the diagnostic severities `error`, `warning`, `info` and `hint`, named as CodeMirror's `Diagnostic.severity` names them. The catppuccin pair keeps its syntax palette — token colors, the editor's default text, the completion-kind icons that mirror them — and gets these baked into its theme colors — Monaco, static rendering, and CodeMirror's chrome all read the same values — so an editor sits inside the app instead of bringing a second dark. A role or scheme left out keeps the flavor's own color, a later call replaces the schemes it names, and values must be hex colors (`#rrggbb`, `#rrggbbaa`) — Monaco parses theme colors as hex and paints red for anything else, so a `var()` reference or an `rgb(…)` is refused up front. Keep `lineHighlight` translucent: CodeMirror draws selections behind the content, so an opaque active line would hide them. `selection` shows at half its alpha while the editor is unfocused, in both engines; `scrollbar` has no hover state (CodeMirror's `scrollbar-color` has none, so Monaco's slider keeps it too). `getEditorSurface(dark)` reads what was configured.
13
+ - **`highlighterSources(highlighter)`** — what the shared highlighter was built from and has loaded since: every grammar registration in the order it was given them (the configured `langs` and every later `loadLanguage` / `loadLanguageSync`, which the highlighter wraps to keep them) and the kind of its engine — `oniguruma` wherever an engine was configured, `javascript` where none was. `@coldsmirk/inkstone-monaco`'s tokenization worker builds a highlighter of the same grammars from it; undefined for a highlighter inkstone did not build.
14
+ - **`configureEditorColors(config)`** — set every color the editors paint that is not syntax (a VS Code theme's `colors`, beside its `tokenColors`) in your design language, once, before any editor mounts. Per scheme, CSS color literals for the editor (`background` — content, gutter and the fields of its chrome — `lineHighlight`, `lineNumber`, `lineNumberActive`, `cursor`, `selection`, `scrollbar`), its floating chrome — completion, hover, parameter hints, the find widget and search panels, the context menu — (`widget`, `widgetBorder`, `widgetSelection`, `widgetForeground`, `widgetForegroundMuted`), the `accent` that rings a focused field and marks what a completion matched, and the diagnostic severities `error`, `warning`, `info` and `hint`, named as CodeMirror's `Diagnostic.severity` names them. The catppuccin pair keeps its syntax palette — token colors, the editor's default text, the completion-kind icons that mirror them — and gets these baked into its theme colors — Monaco, static rendering, and CodeMirror's chrome all read the same values — so an editor sits inside the app instead of bringing a second dark. A role or scheme left out keeps the flavor's own color, a later call replaces the schemes it names, and values must be hex colors (`#rrggbb`, `#rrggbbaa`) — Monaco parses theme colors as hex and paints red for anything else, so a `var()` reference or an `rgb(…)` is refused up front. Keep `lineHighlight` translucent: CodeMirror draws selections behind the content, so an opaque active line would hide them. `selection` shows at half its alpha while the editor is unfocused, in both engines; `scrollbar` has no hover state (CodeMirror's `scrollbar-color` has none, so Monaco's slider keeps it too). `getEditorColors(dark)` reads what was configured, and `withEditorColors(theme, colors)` applies a set of them to a Shiki theme of your own.
14
15
  - **`CODE_FONT_FAMILY`** — the shared code font stack both editor engines render with: the page's `--inkstone-font-family-code` CSS token when defined, else the platform's native monospace.
15
16
  - **`inkstoneRadius(size, fallback)` / `inkstoneShadow(size, fallback)`** — `var()` references to the host's `--inkstone-radius-{small,medium,large,xlarge}` and `--inkstone-shadow-{medium,large,xlarge}` tokens. Set them once on your root and both engines' chrome follows: the Monaco host maps them onto VS Code's `--vscode-cornerRadius-*` / `--vscode-shadow-*` design tokens (which the standalone editor never defines), CodeMirror's polish reads them directly; unset, each engine keeps the look it ships with.
16
17
 
@@ -25,7 +26,7 @@ pnpm add @coldsmirk/inkstone-core
25
26
  ## Quick start
26
27
 
27
28
  ```ts
28
- import { configureEditorSurface, configureHighlighter, DEFAULT_HIGHLIGHTER_LANGS, getHighlighter, onigurumaEngine, shikiThemeId } from "@coldsmirk/inkstone-core";
29
+ import { configureEditorColors, configureHighlighter, DEFAULT_HIGHLIGHTER_LANGS, getHighlighter, onigurumaEngine, shikiThemeId } from "@coldsmirk/inkstone-core";
29
30
  import yaml from "@shikijs/langs/yaml";
30
31
 
31
32
  // Optional: add grammars/themes beyond the defaults — once, before any editor mounts — and,
@@ -33,7 +34,7 @@ import yaml from "@shikijs/langs/yaml";
33
34
  configureHighlighter({ langs: [...DEFAULT_HIGHLIGHTER_LANGS, yaml], engine: onigurumaEngine });
34
35
 
35
36
  // Optional: paint the editors' chrome in your own tokens (syntax colors stay catppuccin's).
36
- configureEditorSurface({
37
+ configureEditorColors({
37
38
  light: { background: "#f7f7fa", lineHighlight: "#16171a0a", widget: "#ffffff", widgetBorder: "#ced4da", accent: "#228be6", error: "#e03131" },
38
39
  dark: { background: "#1d1b22", lineHighlight: "#ffffff0a", widget: "#302e38", widgetBorder: "#423f4b", accent: "#4dabf7", error: "#ff6b6b" }
39
40
  });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Awaitable, HighlighterCore, HighlighterCore as HighlighterCore$1, LanguageInput, LoadWasmOptions, RegexEngine, ThemeInput, ThemeRegistration } from "shiki/core";
1
+ import { Awaitable, HighlighterCore, HighlighterCore as HighlighterCore$1, LanguageInput, LanguageRegistration, LoadWasmOptions, RegexEngine, ThemeInput, ThemeRegistration } from "shiki/core";
2
2
  //#region src/code-font.d.ts
3
3
  /**
4
4
  * The code font stack every inkstone editor host renders with: the page's
@@ -8,19 +8,20 @@ import { Awaitable, HighlighterCore, HighlighterCore as HighlighterCore$1, Langu
8
8
  */
9
9
  declare const CODE_FONT_FAMILY = "var(--inkstone-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)";
10
10
  //#endregion
11
- //#region src/surface.d.ts
11
+ //#region src/editor-colors.d.ts
12
12
  /**
13
- * The colors an editor paints that are not its syntax, as a host's design language names
14
- * them. A host that configures these keeps the catppuccin flavors' syntax palette and gets the
15
- * editor's own chrome — background, gutter, current line, caret and selection, the floating
16
- * completion / hover / find widgets and the signals on them — in its own tokens, so an editor
17
- * sits inside the app instead of bringing a second dark.
13
+ * The colors an editor paints that are not its syntax — a VS Code theme's `colors` beside its
14
+ * `tokenColors` — as a host's design language names them. A host that configures these keeps
15
+ * the catppuccin flavors' syntax palette and gets the editor's own chrome — background, gutter,
16
+ * current line, caret and selection, the floating completion / hover / find widgets and the
17
+ * signals on them — in its own tokens, so an editor sits inside the app instead of bringing a
18
+ * second dark.
18
19
  *
19
20
  * Every value is a hex color (`#rrggbb`, `#rrggbbaa`): Monaco parses its theme colors itself,
20
21
  * as hex only, and cannot follow a custom property. An omitted role keeps the flavor's own
21
22
  * color.
22
23
  */
23
- interface EditorSurface {
24
+ interface EditorColors {
24
25
  /**
25
26
  * The editor's own background: the content area and the gutter, and the fields inside
26
27
  * floating chrome.
@@ -102,12 +103,20 @@ interface EditorSurface {
102
103
  hint?: string;
103
104
  }
104
105
  /**
105
- * One surface per color scheme; an omitted scheme keeps the flavor's own surfaces.
106
+ * The editor colors of each color scheme; an omitted scheme keeps the flavor's own.
106
107
  */
107
- interface EditorSurfaces {
108
- light?: EditorSurface;
109
- dark?: EditorSurface;
108
+ interface EditorColorsConfig {
109
+ light?: EditorColors;
110
+ dark?: EditorColors;
110
111
  }
112
+ /**
113
+ * A flavor with its editor colors repainted from `colors`: the token colors (the syntax
114
+ * palette) are untouched, only the theme colors behind each configured role change. Returns
115
+ * the theme itself when there is nothing to apply.
116
+ */
117
+ declare function withEditorColors(theme: ThemeRegistration, colors: EditorColors | undefined): ThemeRegistration;
118
+ //#endregion
119
+ //#region src/host-tokens.d.ts
111
120
  /**
112
121
  * The corner-radius sizes both editors read from the host: `--inkstone-radius-<size>`. Monaco
113
122
  * maps them onto VS Code's own `--vscode-cornerRadius-*` design tokens (which the standalone
@@ -130,12 +139,6 @@ type ShadowSize = "medium" | "large" | "xlarge";
130
139
  * A `var()` reference to the host's `--inkstone-shadow-<size>` token with the given fallback.
131
140
  */
132
141
  declare function inkstoneShadow(size: ShadowSize, fallback: string): string;
133
- /**
134
- * A flavor with its surfaces repainted from `surface`: the token colors (the syntax palette)
135
- * are untouched, only the theme colors behind each configured role change. Returns the theme
136
- * itself when there is nothing to apply.
137
- */
138
- declare function surfacedTheme(theme: ThemeRegistration, surface: EditorSurface | undefined): ThemeRegistration;
139
142
  //#endregion
140
143
  //#region src/shiki.d.ts
141
144
  /**
@@ -194,6 +197,34 @@ interface HighlighterConfig {
194
197
  * decode it out of a script.
195
198
  */
196
199
  declare function onigurumaEngine(wasm?: LoadWasmOptions): Promise<RegexEngine>;
200
+ /**
201
+ * The regex engine a highlighter built elsewhere from the shared one's grammars tokenizes
202
+ * with, to tokenize as the shared one does: `javascript`, the strict JavaScript engine, where
203
+ * the app configured none; `oniguruma` wherever it configured one. An engine is an object of
204
+ * the page's that cannot be sent anywhere, and Oniguruma is the engine every grammar was
205
+ * written against — the one {@link onigurumaEngine} is, and the one an engine configured for
206
+ * the grammars the strict engine refuses stands in for.
207
+ */
208
+ type HighlighterEngineKind = "javascript" | "oniguruma";
209
+ /**
210
+ * What the shared highlighter was built from, for a highlighter of the same grammars built
211
+ * elsewhere — Monaco's tokenization worker (`@coldsmirk/inkstone-monaco`) is one: every grammar
212
+ * registration it was given, in the order it was given them (shiki builds a grammar again when
213
+ * a language it embeds lazily arrives after it, so the order is part of what was built), and
214
+ * the kind of its engine.
215
+ */
216
+ interface HighlighterSources {
217
+ readonly engine: HighlighterEngineKind;
218
+ /**
219
+ * Grows as the app loads grammars: read it when a copy is due, never once for good.
220
+ */
221
+ readonly languages: readonly LanguageRegistration[];
222
+ }
223
+ /**
224
+ * What the shared highlighter was built from and has loaded since (see
225
+ * {@link HighlighterSources}); undefined for a highlighter inkstone did not build.
226
+ */
227
+ declare function highlighterSources(highlighter: HighlighterCore$1): HighlighterSources | undefined;
197
228
  /**
198
229
  * Configure the shared highlighter before its first use. The highlighter is a process-wide
199
230
  * singleton (editors, static rendering, and markdown surfaces all share it for consistent
@@ -202,23 +233,23 @@ declare function onigurumaEngine(wasm?: LoadWasmOptions): Promise<RegexEngine>;
202
233
  */
203
234
  declare function configureHighlighter(options: HighlighterConfig): void;
204
235
  /**
205
- * Re-light the editors' surfaces in the host's own colors, once, before the first
206
- * {@link getHighlighter} call — the catppuccin pair is registered with these surfaces baked in
207
- * (Monaco reads them from the theme, static rendering too), and CodeMirror's chrome reads them
208
- * at mount. A scheme left out keeps the flavor's own surfaces; a role left out keeps that
209
- * role's flavor color; a later call replaces the schemes it names. Process-global like the
210
- * highlighter itself, for the same reason: one palette across every editor and rendered block.
236
+ * Paint the editors in the host's own colors, once, before the first {@link getHighlighter}
237
+ * call — the catppuccin pair is registered with these colors baked in (Monaco reads them from
238
+ * the theme, static rendering too), and CodeMirror's chrome reads them at mount. A scheme left
239
+ * out keeps the flavor's own colors; a role left out keeps that role's flavor color; a later
240
+ * call replaces the schemes it names. Process-global like the highlighter itself, for the same
241
+ * reason: one palette across every editor and rendered block.
211
242
  *
212
243
  * Every value must be a hex color (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`) — Monaco parses
213
244
  * theme colors as hex and paints red for anything else, a custom property reference or an
214
245
  * `rgb(…)` alike, so those are refused here instead of failing on screen.
215
246
  */
216
- declare function configureEditorSurface(surfaces: EditorSurfaces): void;
247
+ declare function configureEditorColors(config: EditorColorsConfig): void;
217
248
  /**
218
- * The surface configured for a color scheme through {@link configureEditorSurface}, or
219
- * undefined when the flavor's own surfaces stand.
249
+ * The editor colors configured for a color scheme through {@link configureEditorColors}, or
250
+ * undefined when the flavor's own colors stand.
220
251
  */
221
- declare function getEditorSurface(dark: boolean): EditorSurface | undefined;
252
+ declare function getEditorColors(dark: boolean): EditorColors | undefined;
222
253
  /**
223
254
  * The shared Shiki highlighter, built lazily on first call.
224
255
  *
@@ -231,6 +262,9 @@ declare function getEditorSurface(dark: boolean): EditorSurface | undefined;
231
262
  * A failed build is not cached: the slot resets so a later call retries (and
232
263
  * {@link configureHighlighter} becomes callable again), instead of replaying one transient
233
264
  * failure — a chunk 404 after a redeploy, a flaky network — for the rest of the session.
265
+ *
266
+ * The highlighter keeps what it was built from and every grammar loaded into it since, for a
267
+ * highlighter of the same grammars built elsewhere ({@link highlighterSources}).
234
268
  */
235
269
  declare function getHighlighter(): Promise<HighlighterCore$1>;
236
270
  /**
@@ -239,4 +273,4 @@ declare function getHighlighter(): Promise<HighlighterCore$1>;
239
273
  */
240
274
  declare function shikiThemeId(dark: boolean): string;
241
275
  //#endregion
242
- export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, type EditorSurface, type EditorSurfaces, type HighlighterConfig, type HighlighterCore, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME, type RadiusSize, type ShadowSize, configureEditorSurface, configureHighlighter, getEditorSurface, getHighlighter, inkstoneRadius, inkstoneShadow, onigurumaEngine, shikiThemeId, surfacedTheme };
276
+ export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, type EditorColors, type EditorColorsConfig, type HighlighterConfig, type HighlighterCore, type HighlighterEngineKind, type HighlighterSources, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME, type RadiusSize, type ShadowSize, configureEditorColors, configureHighlighter, getEditorColors, getHighlighter, highlighterSources, inkstoneRadius, inkstoneShadow, onigurumaEngine, shikiThemeId, withEditorColors };
package/dist/index.js CHANGED
@@ -4,20 +4,14 @@ import langSql from "@shikijs/langs/sql";
4
4
  import langTypescript from "@shikijs/langs/typescript";
5
5
  import catppuccinLatte from "@shikijs/themes/catppuccin-latte";
6
6
  import catppuccinMacchiato from "@shikijs/themes/catppuccin-macchiato";
7
- import { createHighlighterCore } from "shiki/core";
7
+ import { createHighlighterCore, isSpecialLang, normalizeGetter } from "shiki/core";
8
8
  import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
9
9
  import { createOnigurumaEngine } from "shiki/engine/oniguruma";
10
10
  //#region src/code-font.ts
11
11
  const CODE_FONT_FAMILY = "var(--inkstone-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)";
12
12
  //#endregion
13
- //#region src/surface.ts
14
- function inkstoneRadius(size, fallback) {
15
- return `var(--inkstone-radius-${size}, ${fallback})`;
16
- }
17
- function inkstoneShadow(size, fallback) {
18
- return `var(--inkstone-shadow-${size}, ${fallback})`;
19
- }
20
- const SURFACE_COLORS = {
13
+ //#region src/editor-colors.ts
14
+ const EDITOR_COLOR_KEYS = {
21
15
  background: [
22
16
  "editor.background",
23
17
  "editorGutter.background",
@@ -120,22 +114,30 @@ const SURFACE_COLORS = {
120
114
  ],
121
115
  hint: ["editorHint.foreground"]
122
116
  };
123
- function surfacedTheme(theme, surface) {
124
- const roles = Object.entries(SURFACE_COLORS);
125
- const colors = { ...theme.colors };
117
+ function withEditorColors(theme, colors) {
118
+ const roles = Object.entries(EDITOR_COLOR_KEYS);
119
+ const themeColors = { ...theme.colors };
126
120
  let changed = false;
127
121
  for (const [role, keys] of roles) {
128
- const value = surface?.[role];
122
+ const value = colors?.[role];
129
123
  if (value === void 0) continue;
130
- for (const key of keys) colors[key] = value;
124
+ for (const key of keys) themeColors[key] = value;
131
125
  changed = true;
132
126
  }
133
127
  return changed ? {
134
128
  ...theme,
135
- colors
129
+ colors: themeColors
136
130
  } : theme;
137
131
  }
138
132
  //#endregion
133
+ //#region src/host-tokens.ts
134
+ function inkstoneRadius(size, fallback) {
135
+ return `var(--inkstone-radius-${size}, ${fallback})`;
136
+ }
137
+ function inkstoneShadow(size, fallback) {
138
+ return `var(--inkstone-shadow-${size}, ${fallback})`;
139
+ }
140
+ //#endregion
139
141
  //#region src/shiki.ts
140
142
  const INKSTONE_LIGHT_THEME = "catppuccin-latte";
141
143
  const INKSTONE_DARK_THEME = "catppuccin-macchiato";
@@ -161,13 +163,47 @@ function getHighlighterRegistry() {
161
163
  registry = {
162
164
  config: {},
163
165
  surfaces: {},
164
- promise: null
166
+ promise: null,
167
+ sources: /* @__PURE__ */ new WeakMap()
165
168
  };
166
169
  host[HIGHLIGHTER_REGISTRY_KEY] = registry;
167
170
  }
168
171
  registry.surfaces ??= {};
172
+ registry.sources ??= /* @__PURE__ */ new WeakMap();
169
173
  return registry;
170
174
  }
175
+ async function resolveLanguages(langs) {
176
+ const loaded = await Promise.all(langs.filter((lang) => !isSpecialLang(lang)).map(async (lang) => {
177
+ const registrations = await normalizeGetter(lang);
178
+ return Array.isArray(registrations) ? registrations : [registrations];
179
+ }));
180
+ return [...new Set(loaded.flat())];
181
+ }
182
+ function keepingSources(highlighter, languages, engine, registry) {
183
+ const kept = [...languages];
184
+ const keep = (registrations) => {
185
+ for (const registration of registrations) if (!kept.includes(registration)) kept.push(registration);
186
+ };
187
+ const { loadLanguage, loadLanguageSync } = highlighter;
188
+ highlighter.loadLanguage = async (...langs) => {
189
+ const registrations = await resolveLanguages(langs);
190
+ await loadLanguage(...registrations);
191
+ keep(registrations);
192
+ };
193
+ highlighter.loadLanguageSync = (...langs) => {
194
+ const registrations = [...new Set(langs.flat())];
195
+ loadLanguageSync(...registrations);
196
+ keep(registrations);
197
+ };
198
+ registry.sources.set(highlighter, {
199
+ engine,
200
+ languages: kept
201
+ });
202
+ return highlighter;
203
+ }
204
+ function highlighterSources(highlighter) {
205
+ return getHighlighterRegistry().sources.get(highlighter);
206
+ }
171
207
  function assertConfigurable(registry, caller) {
172
208
  if (registry.promise) throw new Error(`${caller} must be called before the first getHighlighter()`);
173
209
  }
@@ -180,19 +216,19 @@ function configureHighlighter(options) {
180
216
  };
181
217
  }
182
218
  const HEX_COLOR = /^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i;
183
- function configureEditorSurface(surfaces) {
219
+ function configureEditorColors(config) {
184
220
  const registry = getHighlighterRegistry();
185
- assertConfigurable(registry, "configureEditorSurface");
186
- for (const [scheme, surface] of Object.entries(surfaces)) {
187
- const roles = Object.entries(surface ?? {});
188
- for (const [role, value] of roles) if (typeof value === "string" && !HEX_COLOR.test(value)) throw new Error(`configureEditorSurface: ${scheme}.${role} must be a hex color, which is all Monaco parses (${value})`);
221
+ assertConfigurable(registry, "configureEditorColors");
222
+ for (const [scheme, colors] of Object.entries(config)) {
223
+ const roles = Object.entries(colors ?? {});
224
+ for (const [role, value] of roles) if (typeof value === "string" && !HEX_COLOR.test(value)) throw new Error(`configureEditorColors: ${scheme}.${role} must be a hex color, which is all Monaco parses (${value})`);
189
225
  }
190
226
  registry.surfaces = {
191
227
  ...registry.surfaces,
192
- ...surfaces
228
+ ...config
193
229
  };
194
230
  }
195
- function getEditorSurface(dark) {
231
+ function getEditorColors(dark) {
196
232
  const { surfaces } = getHighlighterRegistry();
197
233
  return dark ? surfaces.dark : surfaces.light;
198
234
  }
@@ -200,15 +236,19 @@ function getHighlighter() {
200
236
  const registry = getHighlighterRegistry();
201
237
  const existing = registry.promise;
202
238
  if (existing) return existing;
203
- const attempt = createHighlighterCore({
204
- themes: [
205
- surfacedTheme(catppuccinLatte, registry.surfaces.light),
206
- surfacedTheme(catppuccinMacchiato, registry.surfaces.dark),
207
- ...registry.config.themes ?? []
208
- ],
209
- langs: registry.config.langs ?? [...DEFAULT_HIGHLIGHTER_LANGS],
210
- engine: engineOf(registry.config)
211
- });
239
+ const { config, surfaces } = registry;
240
+ const attempt = (async () => {
241
+ const langs = await resolveLanguages(config.langs ?? DEFAULT_HIGHLIGHTER_LANGS);
242
+ return keepingSources(await createHighlighterCore({
243
+ themes: [
244
+ withEditorColors(catppuccinLatte, surfaces.light),
245
+ withEditorColors(catppuccinMacchiato, surfaces.dark),
246
+ ...config.themes ?? []
247
+ ],
248
+ langs,
249
+ engine: engineOf(config)
250
+ }), langs, config.engine === void 0 ? "javascript" : "oniguruma", registry);
251
+ })();
212
252
  registry.promise = attempt;
213
253
  attempt.catch(() => {
214
254
  if (registry.promise === attempt) registry.promise = null;
@@ -219,4 +259,4 @@ function shikiThemeId(dark) {
219
259
  return dark ? INKSTONE_DARK_THEME : INKSTONE_LIGHT_THEME;
220
260
  }
221
261
  //#endregion
222
- export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME, configureEditorSurface, configureHighlighter, getEditorSurface, getHighlighter, inkstoneRadius, inkstoneShadow, onigurumaEngine, shikiThemeId, surfacedTheme };
262
+ export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME, configureEditorColors, configureHighlighter, getEditorColors, getHighlighter, highlighterSources, inkstoneRadius, inkstoneShadow, onigurumaEngine, shikiThemeId, withEditorColors };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coldsmirk/inkstone-core",
3
- "version": "0.28.1",
3
+ "version": "0.30.0",
4
4
  "description": "Shared Shiki highlighter service for the inkstone editor toolkit: one fine-grained singleton (catppuccin themes, the JS regex engine by default or Oniguruma on request) reused by Monaco, static rendering, and markdown surfaces.",
5
5
  "keywords": [
6
6
  "shiki",