@coldsmirk/inkstone-core 0.20.1 → 0.22.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 +7 -5
- package/dist/index.d.ts +33 -8
- package/dist/index.js +11 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# @coldsmirk/inkstone-core
|
|
2
2
|
|
|
3
|
-
The shared [Shiki](https://shiki.style/) highlighter service behind inkstone: one fine-grained, lazily-created singleton (catppuccin latte / macchiato, JS regex engine) that serves the editors, static code rendering, and markdown surfaces alike — one instance, consistent colors everywhere.
|
|
3
|
+
The shared [Shiki](https://shiki.style/) highlighter service behind inkstone: one fine-grained, lazily-created singleton (catppuccin latte / macchiato, the JS regex engine by default or Oniguruma on request) that serves the editors, static code rendering, and markdown surfaces alike — one instance, consistent colors everywhere.
|
|
4
4
|
|
|
5
5
|
Part of [inkstone](https://github.com/coldsmirk/inkstone). The editor layers ([`@coldsmirk/inkstone-monaco`](https://www.npmjs.com/package/@coldsmirk/inkstone-monaco), [`@coldsmirk/inkstone-codemirror`](https://www.npmjs.com/package/@coldsmirk/inkstone-codemirror)) and the React components ([`@coldsmirk/inkstone-react`](https://www.npmjs.com/package/@coldsmirk/inkstone-react)) consume this package; use it directly when a non-editor surface needs the same highlighting.
|
|
6
6
|
|
|
7
7
|
## What you get
|
|
8
8
|
|
|
9
9
|
- **`getHighlighter()`** — the process-wide `HighlighterCore` promise. JavaScript / TypeScript / JSON / SQL grammars and the catppuccin theme pair load by default.
|
|
10
|
-
- **`configureHighlighter(config)`** — extend or replace the default grammar / theme set, and choose the regex engine
|
|
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
|
+
- **`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")`.
|
|
11
12
|
- **`shikiThemeId(dark)`** plus the `INKSTONE_LIGHT_THEME` / `INKSTONE_DARK_THEME` constants — the theme names to pass wherever a Shiki theme id is expected.
|
|
12
13
|
- **`configureEditorSurface(surfaces)`** — re-light the editors' own surfaces in your design language, once, before any editor mounts: per-scheme CSS color literals for `background` (content and gutter), `lineHighlight`, `lineNumber`, `widget` (completion, hover, parameter hints, the find widget and search panels), `widgetBorder`, and `widgetSelection`. The catppuccin pair keeps its syntax palette 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. `getEditorSurface(dark)` reads what was configured.
|
|
13
14
|
- **`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.
|
|
@@ -24,11 +25,12 @@ pnpm add @coldsmirk/inkstone-core
|
|
|
24
25
|
## Quick start
|
|
25
26
|
|
|
26
27
|
```ts
|
|
27
|
-
import { configureEditorSurface, configureHighlighter, DEFAULT_HIGHLIGHTER_LANGS, getHighlighter, shikiThemeId } from "@coldsmirk/inkstone-core";
|
|
28
|
+
import { configureEditorSurface, configureHighlighter, DEFAULT_HIGHLIGHTER_LANGS, getHighlighter, onigurumaEngine, shikiThemeId } from "@coldsmirk/inkstone-core";
|
|
28
29
|
import yaml from "@shikijs/langs/yaml";
|
|
29
30
|
|
|
30
|
-
// Optional: add grammars/themes beyond the defaults — once, before any editor mounts
|
|
31
|
-
|
|
31
|
+
// Optional: add grammars/themes beyond the defaults — once, before any editor mounts — and,
|
|
32
|
+
// for an app that reads whole files in an editor, the Oniguruma engine (see above).
|
|
33
|
+
configureHighlighter({ langs: [...DEFAULT_HIGHLIGHTER_LANGS, yaml], engine: onigurumaEngine });
|
|
32
34
|
|
|
33
35
|
// Optional: paint the editors' surfaces in your own tokens (syntax colors stay catppuccin's).
|
|
34
36
|
configureEditorSurface({
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HighlighterCore, HighlighterCore as HighlighterCore$1, LanguageInput, RegexEngine, ThemeInput, ThemeRegistration } from "shiki/core";
|
|
1
|
+
import { Awaitable, HighlighterCore, HighlighterCore as HighlighterCore$1, LanguageInput, 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
|
|
@@ -111,12 +111,36 @@ interface HighlighterConfig {
|
|
|
111
111
|
themes?: ThemeInput[];
|
|
112
112
|
/**
|
|
113
113
|
* The regex engine the highlighter tokenizes with, replacing the default JavaScript engine
|
|
114
|
-
* in its strict form
|
|
115
|
-
*
|
|
116
|
-
*
|
|
114
|
+
* in its strict form: the engine itself, a promise of one, or a factory called once when the
|
|
115
|
+
* highlighter is first built — so configuration stays synchronous (it must precede the first
|
|
116
|
+
* {@link getHighlighter}) while the engine may be async to make, as the Oniguruma one is.
|
|
117
|
+
*
|
|
118
|
+
* The JavaScript engine translates each grammar's patterns into JavaScript at the first
|
|
119
|
+
* tokenization, on the main thread, and pays for it on whole files: a TypeScript file's
|
|
120
|
+
* first sixty lines cost it about 170 ms, against Oniguruma's 20. An app that colors fenced
|
|
121
|
+
* snippets keeps the default; one that reads whole files in an editor configures
|
|
122
|
+
* {@link onigurumaEngine}; one whose grammars the strict engine refuses configures
|
|
123
|
+
* `createJavaScriptRegexEngine({ forgiving: true })`.
|
|
117
124
|
*/
|
|
118
|
-
engine?: RegexEngine;
|
|
125
|
+
engine?: Awaitable<RegexEngine> | (() => Awaitable<RegexEngine>);
|
|
119
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* The Oniguruma engine — the one every TextMate grammar was written against, so none is
|
|
129
|
+
* refused and each compiles in a few milliseconds — on its WASM, inlined by `shiki/wasm` into
|
|
130
|
+
* a chunk of the app's own bundle (about 600 KB; nothing is fetched from anywhere else), so
|
|
131
|
+
* it suits an offline or embedded deployment as the JavaScript engine does. Instantiated once,
|
|
132
|
+
* in about 20 ms. Pass the function itself as the engine factory, so the chunk is fetched and
|
|
133
|
+
* the WASM instantiated only when the highlighter is first built:
|
|
134
|
+
*
|
|
135
|
+
* ```ts
|
|
136
|
+
* configureHighlighter({ engine: onigurumaEngine });
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* `wasm` takes the WASM from elsewhere in any form `createOnigurumaEngine` accepts — a
|
|
140
|
+
* `fetch("/onig.wasm")` for a deployment that would rather stream-compile the binary than
|
|
141
|
+
* decode it out of a script.
|
|
142
|
+
*/
|
|
143
|
+
declare function onigurumaEngine(wasm?: LoadWasmOptions): Promise<RegexEngine>;
|
|
120
144
|
/**
|
|
121
145
|
* Configure the shared highlighter before its first use. The highlighter is a process-wide
|
|
122
146
|
* singleton (editors, static rendering, and markdown surfaces all share it for consistent
|
|
@@ -147,8 +171,9 @@ declare function getEditorSurface(dark: boolean): EditorSurface | undefined;
|
|
|
147
171
|
*
|
|
148
172
|
* Fine-grained build: only the configured grammars and the two catppuccin themes are bundled,
|
|
149
173
|
* whereas the convenient `createHighlighter` generates a lazy chunk for *every* Shiki theme and
|
|
150
|
-
* language. The
|
|
151
|
-
*
|
|
174
|
+
* language. The JavaScript regex engine is the default — nothing to instantiate, no WASM in the
|
|
175
|
+
* bundle — and right for fenced snippets; an app reading whole files in an editor configures
|
|
176
|
+
* {@link onigurumaEngine} instead (see {@link HighlighterConfig.engine}).
|
|
152
177
|
*
|
|
153
178
|
* A failed build is not cached: the slot resets so a later call retries (and
|
|
154
179
|
* {@link configureHighlighter} becomes callable again), instead of replaying one transient
|
|
@@ -161,4 +186,4 @@ declare function getHighlighter(): Promise<HighlighterCore$1>;
|
|
|
161
186
|
*/
|
|
162
187
|
declare function shikiThemeId(dark: boolean): string;
|
|
163
188
|
//#endregion
|
|
164
|
-
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, shikiThemeId, surfacedTheme };
|
|
189
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import catppuccinLatte from "@shikijs/themes/catppuccin-latte";
|
|
|
6
6
|
import catppuccinMacchiato from "@shikijs/themes/catppuccin-macchiato";
|
|
7
7
|
import { createHighlighterCore } from "shiki/core";
|
|
8
8
|
import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
|
|
9
|
+
import { createOnigurumaEngine } from "shiki/engine/oniguruma";
|
|
9
10
|
//#region src/code-font.ts
|
|
10
11
|
const CODE_FONT_FAMILY = "var(--inkstone-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)";
|
|
11
12
|
//#endregion
|
|
@@ -75,6 +76,14 @@ const DEFAULT_HIGHLIGHTER_LANGS = [
|
|
|
75
76
|
langJson,
|
|
76
77
|
langSql
|
|
77
78
|
];
|
|
79
|
+
function onigurumaEngine(wasm) {
|
|
80
|
+
return createOnigurumaEngine(wasm ?? import("shiki/wasm"));
|
|
81
|
+
}
|
|
82
|
+
function engineOf(config) {
|
|
83
|
+
const { engine } = config;
|
|
84
|
+
if (typeof engine === "function") return Promise.try(() => engine());
|
|
85
|
+
return engine ?? createJavaScriptRegexEngine();
|
|
86
|
+
}
|
|
78
87
|
const HIGHLIGHTER_REGISTRY_KEY = Symbol.for("coldsmirk.inkstone.shiki.registry");
|
|
79
88
|
function getHighlighterRegistry() {
|
|
80
89
|
const host = globalThis;
|
|
@@ -129,7 +138,7 @@ function getHighlighter() {
|
|
|
129
138
|
...registry.config.themes ?? []
|
|
130
139
|
],
|
|
131
140
|
langs: registry.config.langs ?? [...DEFAULT_HIGHLIGHTER_LANGS],
|
|
132
|
-
engine: registry.config
|
|
141
|
+
engine: engineOf(registry.config)
|
|
133
142
|
});
|
|
134
143
|
registry.promise = attempt;
|
|
135
144
|
attempt.catch(() => {
|
|
@@ -141,4 +150,4 @@ function shikiThemeId(dark) {
|
|
|
141
150
|
return dark ? INKSTONE_DARK_THEME : INKSTONE_LIGHT_THEME;
|
|
142
151
|
}
|
|
143
152
|
//#endregion
|
|
144
|
-
export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME, configureEditorSurface, configureHighlighter, getEditorSurface, getHighlighter, inkstoneRadius, inkstoneShadow, shikiThemeId, surfacedTheme };
|
|
153
|
+
export { CODE_FONT_FAMILY, DEFAULT_HIGHLIGHTER_LANGS, INKSTONE_DARK_THEME, INKSTONE_LIGHT_THEME, configureEditorSurface, configureHighlighter, getEditorSurface, getHighlighter, inkstoneRadius, inkstoneShadow, onigurumaEngine, shikiThemeId, surfacedTheme };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coldsmirk/inkstone-core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Shared Shiki highlighter service for the inkstone editor toolkit: one fine-grained singleton (catppuccin themes, JS regex engine) reused by Monaco, static rendering, and markdown surfaces.",
|
|
3
|
+
"version": "0.22.0",
|
|
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",
|
|
7
7
|
"syntax-highlighting",
|