Compare commits

...

4 Commits

Author SHA1 Message Date
Steven Hall 4c3b88ce30 Disable memcache 2024-04-17 13:27:23 +01:00
Steven Hall a2fc95be6c Test log 2024-04-17 13:15:15 +01:00
Steven Hall e73be147da Fix type 2024-04-17 13:07:03 +01:00
Steven Hall b64f5a6551 Fully dynamic imports of languages 2024-04-17 13:02:03 +01:00
4 changed files with 49 additions and 32 deletions
@@ -11,6 +11,7 @@ export function createHighlightingContext() {
let count = 0;
return () => {
count += 1;
console.log(`Block #${count} / ${CODE_HIGHLIGHT_BLOCK_LIMIT}`)
return count < CODE_HIGHLIGHT_BLOCK_LIMIT;
};
}
@@ -1,13 +1,11 @@
import { DocumentBlockCode, DocumentBlockCodeLine, DocumentInlineAnnotation } from '@gitbook/api';
import {
loadWasm,
ThemedToken,
getHighlighter,
createCssVariablesTheme,
HighlighterGeneric,
bundledLanguages,
bundledThemes,
HighlighterCore,
LanguageInput,
} from 'shiki';
import { getHighlighterCore } from 'shiki/core';
// @ts-ignore - onigWasm is a Wasm module
import onigWasm from 'shiki/onig.wasm?module';
@@ -15,8 +13,6 @@ import { asyncMutexFunction, singleton } from '@/lib/async';
import { getNodeText } from '@/lib/document';
import { trace } from '@/lib/tracing';
import { DocumentContext } from '../DocumentView';
export type HighlightLine = {
highlighted: boolean;
tokens: HighlightToken[];
@@ -35,8 +31,8 @@ type PositionedToken = ThemedToken & { start: number; end: number };
* Highlight a code block while preserving inline elements.
*/
export async function highlight(block: DocumentBlockCode): Promise<HighlightLine[]> {
const langName = block.data.syntax ? getLanguageForSyntax(block.data.syntax) : null;
if (!langName) {
const langName = block.data.syntax; // ? getLanguageForSyntax(block.data.syntax) : null;
if (!langName || !loaders[langName]) {
// Language not found, fallback to plain highlighting
return plainHighlighting(block);
}
@@ -87,16 +83,16 @@ export async function highlight(block: DocumentBlockCode): Promise<HighlightLine
/**
* Validate a language name.
*/
function getLanguageForSyntax(syntax: string): keyof typeof bundledLanguages | null {
// @ts-ignore
const lang = bundledLanguages[syntax];
if (!lang) {
return null;
}
// function getLanguageForSyntax(syntax: string): keyof typeof bundledLanguages | null {
// // @ts-ignore
// const lang = bundledLanguages[syntax];
// if (!lang) {
// return null;
// }
// @ts-ignore
return syntax;
}
// // @ts-ignore
// return syntax;
// }
/**
* Parse a code block without highlighting it.
@@ -305,16 +301,26 @@ function cleanupLine(line: string): string {
*/
const loadHighlighter = singleton(async () => {
return await trace('highlighting.loadHighlighter', async () => {
if (typeof onigWasm !== 'string') {
// When running bun test, the import is a string, we ignore it and let the module
// loads it on its own.
//
// Otherwise for Vercel/Cloudflare, we need to load it ourselves.
await loadWasm((obj) => WebAssembly.instantiate(onigWasm, obj));
}
const highlighter = await getHighlighter({
// if (typeof onigWasm !== 'string') {
// // When running bun test, the import is a string, we ignore it and let the module
// // loads it on its own.
// //
// // Otherwise for Vercel/Cloudflare, we need to load it ourselves.
// await loadWasm((obj) => WebAssembly.instantiate(onigWasm, obj));
// }
const highlighter = await getHighlighterCore({
themes: [createCssVariablesTheme()],
langs: [],
loadWasm:
typeof onigWasm !== 'string'
? async (obj) => {
// When running bun test, the import is a string, we ignore it and let the module
// loads it on its own.
//
// Otherwise for Vercel/Cloudflare, we need to load it ourselves.
return WebAssembly.instantiate(onigWasm, obj);
}
: undefined,
});
return highlighter;
});
@@ -322,8 +328,8 @@ const loadHighlighter = singleton(async () => {
const loadLanguagesMutex = asyncMutexFunction();
async function loadHighlighterLanguage(
highlighter: HighlighterGeneric<keyof typeof bundledLanguages, keyof typeof bundledThemes>,
lang: keyof typeof bundledLanguages,
highlighter: HighlighterCore,
lang: string,
) {
await loadLanguagesMutex.runBlocking(async () => {
if (highlighter.getLoadedLanguages().includes(lang)) {
@@ -332,7 +338,13 @@ async function loadHighlighterLanguage(
await trace(
`highlighting.loadLanguage(${lang})`,
async () => await highlighter.loadLanguage(lang),
async () => await highlighter.loadLanguage(loaders[lang]),
);
});
}
const loaders: { [key: string]: LanguageInput } = {
javascript: () => import('shiki/langs/javascript.mjs'),
typescript: () => import('shiki/langs/typescript.mjs'),
tsx: () => import('shiki/langs/tsx.mjs'),
}
+6 -2
View File
@@ -33,7 +33,9 @@ export function Header(props: {
const isCustomizationDefault =
customization.header.preset === CustomizationHeaderPreset.Default;
const isMultiVariants = parent?.object === 'collection' || (parent && parent.object === 'site' && spaces.length > 1)
const isMultiVariants =
parent?.object === 'collection' ||
(parent && parent.object === 'site' && spaces.length > 1);
return (
<header
@@ -74,7 +76,9 @@ export function Header(props: {
)}
>
<HeaderLogo parent={parent} space={space} customization={customization} />
<span>{isMultiVariants ? <SpacesDropdown space={space} spaces={spaces} /> : null}</span>
<span>
{isMultiVariants ? <SpacesDropdown space={space} spaces={spaces} /> : null}
</span>
<HeaderLinks>
{customization.header.links.map((link, index) => {
return (
+1 -1
View File
@@ -6,7 +6,7 @@ import { redisCache } from './redis';
export const cacheBackends = [
// Cache local to the process
// (can't be globally purged or shared between processes)
memoryCache,
// memoryCache,
// Global cache shared between all processes
// with proper replication and invalidation
// redisCache, // Disabled as we investigate high amount of fetch requests