@shikijs/core 1.6.5 → 1.8.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/dist/chunk-tokens.d.mts +5 -0
- package/dist/index.mjs +97 -15
- package/dist/types.d.mts +8 -0
- package/package.json +1 -1
package/dist/chunk-tokens.d.mts
CHANGED
|
@@ -1005,6 +1005,11 @@ interface HighlighterCoreOptions {
|
|
|
1005
1005
|
* Load wasm file from a custom path or using a custom function.
|
|
1006
1006
|
*/
|
|
1007
1007
|
loadWasm?: LoadWasmOptions;
|
|
1008
|
+
/**
|
|
1009
|
+
* Emit console warnings to alert users of potential issues.
|
|
1010
|
+
* @default true
|
|
1011
|
+
*/
|
|
1012
|
+
warnings?: boolean;
|
|
1008
1013
|
}
|
|
1009
1014
|
interface BundledHighlighterOptions<L extends string, T extends string> {
|
|
1010
1015
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -4651,6 +4651,50 @@ async function main(init) {
|
|
|
4651
4651
|
}
|
|
4652
4652
|
return false;
|
|
4653
4653
|
}
|
|
4654
|
+
const UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
|
|
4655
|
+
function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead = 1024) {
|
|
4656
|
+
const endIdx = idx + maxBytesToRead;
|
|
4657
|
+
let endPtr = idx;
|
|
4658
|
+
while (heapOrArray[endPtr] && !(endPtr >= endIdx))
|
|
4659
|
+
++endPtr;
|
|
4660
|
+
if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
|
|
4661
|
+
return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
|
|
4662
|
+
}
|
|
4663
|
+
let str = '';
|
|
4664
|
+
while (idx < endPtr) {
|
|
4665
|
+
let u0 = heapOrArray[idx++];
|
|
4666
|
+
if (!(u0 & 128)) {
|
|
4667
|
+
str += String.fromCharCode(u0);
|
|
4668
|
+
continue;
|
|
4669
|
+
}
|
|
4670
|
+
const u1 = heapOrArray[idx++] & 63;
|
|
4671
|
+
if ((u0 & 224) === 192) {
|
|
4672
|
+
str += String.fromCharCode(((u0 & 31) << 6) | u1);
|
|
4673
|
+
continue;
|
|
4674
|
+
}
|
|
4675
|
+
const u2 = heapOrArray[idx++] & 63;
|
|
4676
|
+
if ((u0 & 240) === 224) {
|
|
4677
|
+
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
|
|
4678
|
+
}
|
|
4679
|
+
else {
|
|
4680
|
+
u0 = ((u0 & 7) << 18)
|
|
4681
|
+
| (u1 << 12)
|
|
4682
|
+
| (u2 << 6)
|
|
4683
|
+
| (heapOrArray[idx++] & 63);
|
|
4684
|
+
}
|
|
4685
|
+
if (u0 < 65536) {
|
|
4686
|
+
str += String.fromCharCode(u0);
|
|
4687
|
+
}
|
|
4688
|
+
else {
|
|
4689
|
+
const ch = u0 - 65536;
|
|
4690
|
+
str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
|
|
4691
|
+
}
|
|
4692
|
+
}
|
|
4693
|
+
return str;
|
|
4694
|
+
}
|
|
4695
|
+
function UTF8ToString(ptr, maxBytesToRead) {
|
|
4696
|
+
return ptr ? UTF8ArrayToString(binding.HEAPU8, ptr, maxBytesToRead) : '';
|
|
4697
|
+
}
|
|
4654
4698
|
const asmLibraryArg = {
|
|
4655
4699
|
emscripten_get_now: _emscripten_get_now,
|
|
4656
4700
|
emscripten_memcpy_big: _emscripten_memcpy_big,
|
|
@@ -4666,6 +4710,7 @@ async function main(init) {
|
|
|
4666
4710
|
wasmMemory = exports.memory;
|
|
4667
4711
|
updateGlobalBufferAndViews(wasmMemory.buffer);
|
|
4668
4712
|
Object.assign(binding, exports);
|
|
4713
|
+
binding.UTF8ToString = UTF8ToString;
|
|
4669
4714
|
}
|
|
4670
4715
|
await createWasm();
|
|
4671
4716
|
return binding;
|
|
@@ -5154,9 +5199,9 @@ class Registry extends Registry$1 {
|
|
|
5154
5199
|
_themes;
|
|
5155
5200
|
_langs;
|
|
5156
5201
|
_alias;
|
|
5157
|
-
_resolvedThemes =
|
|
5158
|
-
_resolvedGrammars =
|
|
5159
|
-
_langMap =
|
|
5202
|
+
_resolvedThemes = new Map();
|
|
5203
|
+
_resolvedGrammars = new Map();
|
|
5204
|
+
_langMap = new Map();
|
|
5160
5205
|
_langGraph = new Map();
|
|
5161
5206
|
_textmateThemeCache = new WeakMap();
|
|
5162
5207
|
_loadedThemesCache = null;
|
|
@@ -5172,14 +5217,14 @@ class Registry extends Registry$1 {
|
|
|
5172
5217
|
}
|
|
5173
5218
|
getTheme(theme) {
|
|
5174
5219
|
if (typeof theme === 'string')
|
|
5175
|
-
return this._resolvedThemes
|
|
5220
|
+
return this._resolvedThemes.get(theme);
|
|
5176
5221
|
else
|
|
5177
5222
|
return this.loadTheme(theme);
|
|
5178
5223
|
}
|
|
5179
5224
|
loadTheme(theme) {
|
|
5180
5225
|
const _theme = normalizeTheme(theme);
|
|
5181
5226
|
if (_theme.name) {
|
|
5182
|
-
this._resolvedThemes
|
|
5227
|
+
this._resolvedThemes.set(_theme.name, _theme);
|
|
5183
5228
|
// Reset cache
|
|
5184
5229
|
this._loadedThemesCache = null;
|
|
5185
5230
|
}
|
|
@@ -5187,7 +5232,7 @@ class Registry extends Registry$1 {
|
|
|
5187
5232
|
}
|
|
5188
5233
|
getLoadedThemes() {
|
|
5189
5234
|
if (!this._loadedThemesCache)
|
|
5190
|
-
this._loadedThemesCache =
|
|
5235
|
+
this._loadedThemesCache = [...this._resolvedThemes.keys()];
|
|
5191
5236
|
return this._loadedThemesCache;
|
|
5192
5237
|
}
|
|
5193
5238
|
// Override and re-implement this method to cache the textmate themes as `TextMateTheme.createFromRawTheme`
|
|
@@ -5214,12 +5259,13 @@ class Registry extends Registry$1 {
|
|
|
5214
5259
|
resolved.add(name);
|
|
5215
5260
|
}
|
|
5216
5261
|
}
|
|
5217
|
-
return this._resolvedGrammars
|
|
5262
|
+
return this._resolvedGrammars.get(name);
|
|
5218
5263
|
}
|
|
5219
5264
|
async loadLanguage(lang) {
|
|
5220
5265
|
if (this.getGrammar(lang.name))
|
|
5221
5266
|
return;
|
|
5222
|
-
const embeddedLazilyBy = new Set(
|
|
5267
|
+
const embeddedLazilyBy = new Set([...this._langMap.values()]
|
|
5268
|
+
.filter(i => i.embeddedLangsLazy?.includes(lang.name)));
|
|
5223
5269
|
this._resolver.addLanguage(lang);
|
|
5224
5270
|
const grammarConfig = {
|
|
5225
5271
|
balancedBracketSelectors: lang.balancedBracketSelectors || ['*'],
|
|
@@ -5228,7 +5274,7 @@ class Registry extends Registry$1 {
|
|
|
5228
5274
|
// @ts-expect-error Private members, set this to override the previous grammar (that can be a stub)
|
|
5229
5275
|
this._syncRegistry._rawGrammars.set(lang.scopeName, lang);
|
|
5230
5276
|
const g = await this.loadGrammarWithConfiguration(lang.scopeName, 1, grammarConfig);
|
|
5231
|
-
this._resolvedGrammars
|
|
5277
|
+
this._resolvedGrammars.set(lang.name, g);
|
|
5232
5278
|
if (lang.aliases) {
|
|
5233
5279
|
lang.aliases.forEach((alias) => {
|
|
5234
5280
|
this._alias[alias] = lang.name;
|
|
@@ -5239,14 +5285,14 @@ class Registry extends Registry$1 {
|
|
|
5239
5285
|
// If there is a language that embeds this language lazily, we need to reload it
|
|
5240
5286
|
if (embeddedLazilyBy.size) {
|
|
5241
5287
|
for (const e of embeddedLazilyBy) {
|
|
5242
|
-
|
|
5288
|
+
this._resolvedGrammars.delete(e.name);
|
|
5243
5289
|
// Reset cache
|
|
5244
5290
|
this._loadedLanguagesCache = null;
|
|
5245
5291
|
// @ts-expect-error clear cache
|
|
5246
5292
|
this._syncRegistry?._injectionGrammars?.delete(e.scopeName);
|
|
5247
5293
|
// @ts-expect-error clear cache
|
|
5248
5294
|
this._syncRegistry?._grammars?.delete(e.scopeName);
|
|
5249
|
-
await this.loadLanguage(this._langMap
|
|
5295
|
+
await this.loadLanguage(this._langMap.get(e.name));
|
|
5250
5296
|
}
|
|
5251
5297
|
}
|
|
5252
5298
|
}
|
|
@@ -5254,6 +5300,14 @@ class Registry extends Registry$1 {
|
|
|
5254
5300
|
this._themes.map(t => this.loadTheme(t));
|
|
5255
5301
|
await this.loadLanguages(this._langs);
|
|
5256
5302
|
}
|
|
5303
|
+
dispose() {
|
|
5304
|
+
super.dispose();
|
|
5305
|
+
this._resolvedThemes.clear();
|
|
5306
|
+
this._resolvedGrammars.clear();
|
|
5307
|
+
this._langMap.clear();
|
|
5308
|
+
this._langGraph.clear();
|
|
5309
|
+
this._loadedThemesCache = null;
|
|
5310
|
+
}
|
|
5257
5311
|
async loadLanguages(langs) {
|
|
5258
5312
|
for (const lang of langs)
|
|
5259
5313
|
this.resolveEmbeddedLanguages(lang);
|
|
@@ -5271,16 +5325,19 @@ class Registry extends Registry$1 {
|
|
|
5271
5325
|
await this.loadLanguage(lang);
|
|
5272
5326
|
}
|
|
5273
5327
|
getLoadedLanguages() {
|
|
5274
|
-
if (!this._loadedLanguagesCache)
|
|
5275
|
-
this._loadedLanguagesCache =
|
|
5328
|
+
if (!this._loadedLanguagesCache) {
|
|
5329
|
+
this._loadedLanguagesCache = [
|
|
5330
|
+
...new Set([...this._resolvedGrammars.keys(), ...Object.keys(this._alias)]),
|
|
5331
|
+
];
|
|
5332
|
+
}
|
|
5276
5333
|
return this._loadedLanguagesCache;
|
|
5277
5334
|
}
|
|
5278
5335
|
resolveEmbeddedLanguages(lang) {
|
|
5279
|
-
this._langMap
|
|
5336
|
+
this._langMap.set(lang.name, lang);
|
|
5280
5337
|
this._langGraph.set(lang.name, lang);
|
|
5281
5338
|
if (lang.embeddedLangs) {
|
|
5282
5339
|
for (const embeddedLang of lang.embeddedLangs)
|
|
5283
|
-
this._langGraph.set(embeddedLang, this._langMap
|
|
5340
|
+
this._langGraph.set(embeddedLang, this._langMap.get(embeddedLang));
|
|
5284
5341
|
}
|
|
5285
5342
|
}
|
|
5286
5343
|
}
|
|
@@ -5338,10 +5395,15 @@ let _defaultWasmLoader;
|
|
|
5338
5395
|
function setDefaultWasmLoader(_loader) {
|
|
5339
5396
|
_defaultWasmLoader = _loader;
|
|
5340
5397
|
}
|
|
5398
|
+
let instancesCount = 0;
|
|
5341
5399
|
/**
|
|
5342
5400
|
* Get the minimal shiki context for rendering.
|
|
5343
5401
|
*/
|
|
5344
5402
|
async function getShikiInternal(options = {}) {
|
|
5403
|
+
instancesCount += 1;
|
|
5404
|
+
if (options.warnings !== false && instancesCount >= 10 && instancesCount % 10 === 0)
|
|
5405
|
+
console.warn(`[Shiki] ${instancesCount} instances have been created. Shiki is supposed to be used as a singleton, consider refactoring your code to cache your highlighter instance; Or call \`highlighter.dispose()\` to release unused instances.`);
|
|
5406
|
+
let isDisposed = false;
|
|
5345
5407
|
async function normalizeGetter(p) {
|
|
5346
5408
|
return Promise.resolve(typeof p === 'function' ? p() : p).then(r => r.default || r);
|
|
5347
5409
|
}
|
|
@@ -5368,6 +5430,7 @@ async function getShikiInternal(options = {}) {
|
|
|
5368
5430
|
await _registry.init();
|
|
5369
5431
|
let _lastTheme;
|
|
5370
5432
|
function getLanguage(name) {
|
|
5433
|
+
ensureNotDisposed();
|
|
5371
5434
|
const _lang = _registry.getGrammar(typeof name === 'string' ? name : name.name);
|
|
5372
5435
|
if (!_lang)
|
|
5373
5436
|
throw new ShikiError(`Language \`${name}\` not found, you may need to load it first`);
|
|
@@ -5376,12 +5439,14 @@ async function getShikiInternal(options = {}) {
|
|
|
5376
5439
|
function getTheme(name) {
|
|
5377
5440
|
if (name === 'none')
|
|
5378
5441
|
return { bg: '', fg: '', name: 'none', settings: [], type: 'dark' };
|
|
5442
|
+
ensureNotDisposed();
|
|
5379
5443
|
const _theme = _registry.getTheme(name);
|
|
5380
5444
|
if (!_theme)
|
|
5381
5445
|
throw new ShikiError(`Theme \`${name}\` not found, you may need to load it first`);
|
|
5382
5446
|
return _theme;
|
|
5383
5447
|
}
|
|
5384
5448
|
function setTheme(name) {
|
|
5449
|
+
ensureNotDisposed();
|
|
5385
5450
|
const theme = getTheme(name);
|
|
5386
5451
|
if (_lastTheme !== name) {
|
|
5387
5452
|
_registry.setTheme(theme);
|
|
@@ -5394,19 +5459,34 @@ async function getShikiInternal(options = {}) {
|
|
|
5394
5459
|
};
|
|
5395
5460
|
}
|
|
5396
5461
|
function getLoadedThemes() {
|
|
5462
|
+
ensureNotDisposed();
|
|
5397
5463
|
return _registry.getLoadedThemes();
|
|
5398
5464
|
}
|
|
5399
5465
|
function getLoadedLanguages() {
|
|
5466
|
+
ensureNotDisposed();
|
|
5400
5467
|
return _registry.getLoadedLanguages();
|
|
5401
5468
|
}
|
|
5402
5469
|
async function loadLanguage(...langs) {
|
|
5470
|
+
ensureNotDisposed();
|
|
5403
5471
|
await _registry.loadLanguages(await resolveLangs(langs));
|
|
5404
5472
|
}
|
|
5405
5473
|
async function loadTheme(...themes) {
|
|
5474
|
+
ensureNotDisposed();
|
|
5406
5475
|
await Promise.all(themes.map(async (theme) => isSpecialTheme(theme)
|
|
5407
5476
|
? null
|
|
5408
5477
|
: _registry.loadTheme(await normalizeGetter(theme))));
|
|
5409
5478
|
}
|
|
5479
|
+
function ensureNotDisposed() {
|
|
5480
|
+
if (isDisposed)
|
|
5481
|
+
throw new ShikiError('Shiki instance has been disposed');
|
|
5482
|
+
}
|
|
5483
|
+
function dispose() {
|
|
5484
|
+
if (isDisposed)
|
|
5485
|
+
return;
|
|
5486
|
+
isDisposed = true;
|
|
5487
|
+
_registry.dispose();
|
|
5488
|
+
instancesCount -= 1;
|
|
5489
|
+
}
|
|
5410
5490
|
return {
|
|
5411
5491
|
setTheme,
|
|
5412
5492
|
getTheme,
|
|
@@ -5415,6 +5495,8 @@ async function getShikiInternal(options = {}) {
|
|
|
5415
5495
|
getLoadedLanguages,
|
|
5416
5496
|
loadLanguage,
|
|
5417
5497
|
loadTheme,
|
|
5498
|
+
dispose,
|
|
5499
|
+
[Symbol.dispose]: dispose,
|
|
5418
5500
|
};
|
|
5419
5501
|
}
|
|
5420
5502
|
|
package/dist/types.d.mts
CHANGED
|
@@ -42,6 +42,14 @@ interface ShikiInternal<BundledLangKeys extends string = never, BundledThemeKeys
|
|
|
42
42
|
* Special-handled themes like `none` are not included.
|
|
43
43
|
*/
|
|
44
44
|
getLoadedThemes: () => string[];
|
|
45
|
+
/**
|
|
46
|
+
* Dispose the internal registry and release resources
|
|
47
|
+
*/
|
|
48
|
+
dispose: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Dispose the internal registry and release resources
|
|
51
|
+
*/
|
|
52
|
+
[Symbol.dispose]: () => void;
|
|
45
53
|
}
|
|
46
54
|
/**
|
|
47
55
|
* Generic instance interface of Shiki
|