Skip to content

Commit

Permalink
refactor: more robust setup injection
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Mar 8, 2024
1 parent 05196b6 commit 9694c53
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 108 deletions.
8 changes: 2 additions & 6 deletions demo/vue-runner/setup/shiki.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import type { ShikiSetupReturn } from '@slidev/types'
import { defineShikiSetup } from '@slidev/types'

export default defineShikiSetup(() => {
export default defineShikiSetup((): ShikiSetupReturn => {
return {
themes: {
dark: 'vitesse-dark',
light: 'vitesse-light',
},
// Explicitly Vue for Monaco Highlighting
langs: [
'ts',
'js',
Expand Down
3 changes: 2 additions & 1 deletion packages/client/internals/SideEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { throttledWatch, useEventListener } from '@vueuse/core'
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { activeElement, editorHeight, editorWidth, isInputting, showEditor, isEditorVertical as vertical } from '../state'
import { useCodeMirror } from '../setup/codemirror'
import { useCodeMirror } from '../modules/codemirror'
import { currentSlideNo, openInEditor } from '../logic/nav'
import { useDynamicSlideInfo } from '../composables/useSlideInfo'
import IconButton from './IconButton.vue'
Expand Down Expand Up @@ -219,3 +219,4 @@ throttledWatch(
@apply px-3 py-2 h-full overflow-hidden bg-transparent font-mono text-sm z-0;
}
</style>
../modules/codemirror
File renamed without changes.
17 changes: 6 additions & 11 deletions packages/client/setup/code-runners.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* __imports__ */
import { createSingletonPromise } from '@antfu/utils'
import type { CodeRunner, CodeRunnerContext, CodeRunnerOutput, CodeRunnerOutputText, CodeRunnerOutputs, CodeRunnerProviders } from '@slidev/types'
import type { CodeRunner, CodeRunnerContext, CodeRunnerOutput, CodeRunnerOutputText, CodeRunnerOutputs } from '@slidev/types'
import type { CodeToHastOptions } from 'shiki'
import { isDark } from '../logic/dark'
import setups from '#slidev/setups/code-runners'

export default createSingletonPromise(async () => {
const runners: Record<string, CodeRunner> = {
Expand Down Expand Up @@ -48,15 +48,10 @@ export default createSingletonPromise(async () => {
}
}

// @ts-expect-error injected in runtime
// eslint-disable-next-line unused-imports/no-unused-vars
const injection_arg = runners
// eslint-disable-next-line prefer-const
let injection_return: CodeRunnerProviders = {}

/* __async_injections__ */

Object.assign(runners, injection_return)
for (const setup of setups) {
const result = await setup(runners)
Object.assign(runners, result)
}

return {
highlight,
Expand Down
12 changes: 4 additions & 8 deletions packages/client/setup/main.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/* __imports__ */

import type { AppContext } from '@slidev/types'
import { MotionPlugin } from '@vueuse/motion'
import TwoSlashFloatingVue from '@shikijs/vitepress-twoslash/client'
import setups from '#slidev/setups/main'

export default function setupMain(context: AppContext) {
export default async function setupMain(context: AppContext) {
function setMaxHeight() {
// disable the mobile navbar scroll
// see https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
Expand All @@ -16,9 +15,6 @@ export default function setupMain(context: AppContext) {
context.app.use(MotionPlugin)
context.app.use(TwoSlashFloatingVue as any)

// @ts-expect-error inject in runtime
// eslint-disable-next-line unused-imports/no-unused-vars
const injection_arg = context

/* __injections__ */
for (const setup of setups)
await setup(context)
}
11 changes: 5 additions & 6 deletions packages/client/setup/mermaid.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/* __imports__ */

import type { MermaidOptions } from '@slidev/types'
import { defineMermaidSetup } from '@slidev/types'
import setups from '#slidev/setups/mermaid'

export default defineMermaidSetup(() => {
// eslint-disable-next-line prefer-const
let injection_return: MermaidOptions = {
const setupReturn: MermaidOptions = {
theme: 'default',
}

/* __injections__ */
for (const setup of setups)
Object.assign(setupReturn, setup())

return injection_return
return setupReturn
})
16 changes: 7 additions & 9 deletions packages/client/setup/monaco.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import { StandaloneServices } from 'monaco-editor/esm/vs/editor/standalone/brows

import { isDark } from '../logic/dark'
import configs from '#slidev/configs'
import setups from '#slidev/setups/monaco'

/* __imports__ */
window.MonacoEnvironment = {
getWorker(_, label) {
if (label === 'json')
Expand Down Expand Up @@ -98,13 +98,11 @@ const setup = createSingletonPromise(async () => {
const { shiki, themes, shikiToMonaco } = await import('#slidev/shiki')
const highlighter = await shiki

// @ts-expect-error injected in runtime
// eslint-disable-next-line unused-imports/no-unused-vars
const injection_arg = monaco
// eslint-disable-next-line prefer-const
let injection_return: MonacoSetupReturn = {}

/* __async_injections__ */
const setupReturn: MonacoSetupReturn = {}
for (const setup of setups) {
const result = await setup(monaco)
Object.assign(setupReturn, result)
}

// Use Shiki to highlight Monaco
shikiToMonaco(highlighter, monaco)
Expand All @@ -122,7 +120,7 @@ const setup = createSingletonPromise(async () => {
return {
monaco,
ata,
...injection_return,
...setupReturn,
}
})

Expand Down
43 changes: 0 additions & 43 deletions packages/client/setup/prettier.ts

This file was deleted.

9 changes: 3 additions & 6 deletions packages/client/setup/root.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* __imports__ */
import { watch } from 'vue'
import { useHead } from '@unhead/vue'
import { configs } from '../env'
Expand All @@ -9,13 +8,11 @@ import { router } from '../routes'
import { TRUST_ORIGINS } from '../constants'
import { skipTransition } from '../composables/hmr'
import { makeId } from '../logic/utils'
import setups from '#slidev/setups/root'

export default function setupRoot() {
// @ts-expect-error injected in runtime
// eslint-disable-next-line unused-imports/no-unused-vars
const injection_arg = undefined

/* __injections__ */
for (const setup of setups)
setup()

const title = configs.titleTemplate.replace('%s', configs.title || 'Slidev')
useHead({
Expand Down
20 changes: 10 additions & 10 deletions packages/client/setup/shortcuts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* __imports__ */
import { and, not, or } from '@vueuse/math'
import type { NavOperations, ShortcutOptions } from '@slidev/types'
import { downloadPDF } from '../utils'
Expand All @@ -7,13 +6,12 @@ import { toggleDark } from '../logic/dark'
import { magicKeys, showGotoDialog, showOverview, toggleOverview } from '../state'
import { drawingEnabled } from '../logic/drawings'
import { currentOverviewPage, downOverviewPage, nextOverviewPage, prevOverviewPage, upOverviewPage } from './../logic/overview'
import setups from '#slidev/setups/shortcuts'

export default function setupShortcuts() {
const { escape, space, shift, left, right, up, down, enter, d, g, o, '`': backtick } = magicKeys

// @ts-expect-error injected in runtime
// eslint-disable-next-line unused-imports/no-unused-vars
const injection_arg: NavOperations = {
const context: NavOperations = {
next,
prev,
nextSlide,
Expand All @@ -29,8 +27,7 @@ export default function setupShortcuts() {
showGotoDialog: () => showGotoDialog.value = !showGotoDialog.value,
}

// eslint-disable-next-line prefer-const
let injection_return: ShortcutOptions[] = [
let shortcuts: ShortcutOptions[] = [
{ name: 'next_space', key: and(space, not(shift)), fn: next, autoRepeat: true },
{ name: 'prev_space', key: and(space, shift), fn: prev, autoRepeat: true },
{ name: 'next_right', key: and(right, not(shift), not(showOverview)), fn: next, autoRepeat: true },
Expand Down Expand Up @@ -59,11 +56,14 @@ export default function setupShortcuts() {
},
]

const baseShortcutNames = new Set(injection_return.map(s => s.name))
const baseShortcutNames = new Set(shortcuts.map(s => s.name))

/* __chained_injections__ */
for (const setup of setups) {
const result = setup(context, shortcuts)
shortcuts = shortcuts.concat(result)
}

const remainingBaseShortcutNames = injection_return.filter(s => s.name && baseShortcutNames.has(s.name))
const remainingBaseShortcutNames = shortcuts.filter(s => s.name && baseShortcutNames.has(s.name))
if (remainingBaseShortcutNames.length === 0) {
const message = [
'========== WARNING ==========',
Expand All @@ -77,5 +77,5 @@ export default function setupShortcuts() {
console.warn(message)
}

return injection_return
return shortcuts
}
3 changes: 2 additions & 1 deletion packages/create-theme/template/setup/shiki.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ShikiSetupReturn } from '@slidev/types'
import { defineShikiSetup } from '@slidev/types'

export default defineShikiSetup(() => {
export default defineShikiSetup((): ShikiSetupReturn => {
return {
themes: {
dark: 'vitesse-dark',
Expand Down
34 changes: 33 additions & 1 deletion packages/slidev/node/plugins/loaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ function withRenderedNote(data: SlideInfo): SlideInfo {
}

export function createSlidesLoader(
{ data, clientRoot, roots, remote, mode, userRoot }: ResolvedSlidevOptions,
{ data, clientRoot, roots, remote, mode, userRoot, themeRoots, addonRoots }: ResolvedSlidevOptions,
pluginOptions: SlidevPluginOptions,
serverOptions: SlidevServerOptions,
): Plugin[] {
Expand Down Expand Up @@ -288,6 +288,13 @@ export function createSlidesLoader(
if (id === '/@slidev/shiki')
return generteShikiBundle()

// setups
const setupModules = ['shiki', 'code-runners', 'monaco', 'mermaid', 'main', 'root', 'shortcuts']
for (const name of setupModules) {
if (id === `/@slidev/setups/${name}`)
return generateSetupArray(name)
}

// title
if (id === '/@slidev/titles.md') {
return {
Expand Down Expand Up @@ -825,6 +832,31 @@ export default {
`
}

async function generateSetupArray(name: string) {
const setups = uniq([
...themeRoots,
...addonRoots,
userRoot,
])
.flatMap((i) => {
const path = join(i, 'setup', name)
return ['.ts', '.mts', '.js', '.mjs'].map(ext => path + ext)
})
.filter(i => fs.existsSync(i))

const imports: string[] = []

setups.forEach((path, idx) => {
imports.push(`import __n${idx} from '${toAtFS(path)}'`)
})

imports.push(
`export default [${setups.map((_, idx) => `__n${idx}`).join(',')}]`,
)

return imports.join('\n')
}

async function generteShikiBundle() {
const options = await loadShikiSetups(clientRoot, roots)
const langs = await resolveLangs(options.langs || ['javascript', 'typescript', 'html', 'css'])
Expand Down
3 changes: 1 addition & 2 deletions packages/slidev/node/plugins/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { ResolvedSlidevOptions, SlidevPluginOptions, SlidevServerOptions }
import { loadDrawings, writeDrawings } from '../drawings'
import { createConfigPlugin } from './extendConfig'
import { createSlidesLoader } from './loaders'
import { createClientSetupPlugin } from './setupClient'

import { createMarkdownPlugin } from './markdown'
import { createFixPlugins } from './patchTransform'
import { createMonacoTypesLoader } from './monacoTypes'
Expand Down Expand Up @@ -169,7 +169,6 @@ export async function ViteSlidevPlugin(
}),

createConfigPlugin(options),
createClientSetupPlugin(options),
createMonacoTypesLoader(options),
createFixPlugins(options),

Expand Down
42 changes: 42 additions & 0 deletions packages/types/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,48 @@ declare module '#slidev/shiki' {
export const shiki: Promise<ShikiHighlighterCore>
}

declare module '#slidev/setups/monaco' {
import type { MonacoSetup } from '@slidev/types'

const setups: MonacoSetup[]
export default setups
}

declare module '#slidev/setups/code-runners' {
import type { CodeRunnersSetup } from '@slidev/types'

const setups: CodeRunnersSetup[]
export default setups
}

declare module '#slidev/setups/mermaid' {
import type { MermaidSetup } from '@slidev/types'

const setups: MermaidSetup[]
export default setups
}

declare module '#slidev/setups/main' {
import type { AppSetup } from '@slidev/types'

const setups: AppSetup[]
export default setups
}

declare module '#slidev/setups/root' {
import type { RootSetup } from '@slidev/types'

const setups: RootSetup[]
export default setups
}

declare module '#slidev/setups/shortcuts' {
import type { ShortcutsSetup } from '@slidev/types'

const setups: ShortcutsSetup[]
export default setups
}

declare module '#slidev/styles' {
// side-effects only
}
Expand Down
Loading

0 comments on commit 9694c53

Please sign in to comment.