@stackoverfloweth/prefect-design
Version:
A collection of low-level Vue components.
52 lines (43 loc) • 1.62 kB
text/typescript
import { computed, MaybeRefOrGetter, onScopeDispose, Ref, ref, toValue, watchEffect } from 'vue'
import HighlightWorker from '@/components/CodeHighlight/worker?worker&inline'
import { FormattedMessagePayload, UnformattedMessagePayload } from '@/types/codeHighlight'
import { randomId } from '@/utilities'
export type HighlightCallback = (payload: FormattedMessagePayload) => void
export type UseCodeHighlight = {
formatted: Ref<string>,
lines: Ref<number>,
illegal: Ref<boolean>,
relevance: Ref<number>,
}
const callbacks = new Map<string, HighlightCallback>()
const worker = new HighlightWorker()
worker.onmessage = (message: MessageEvent<FormattedMessagePayload>) => {
const { id } = message.data
const callback = callbacks.get(id)
if (callback) {
callback(message.data)
}
}
export function useCodeHighlight(text: MaybeRefOrGetter, language: MaybeRefOrGetter): UseCodeHighlight {
const id = randomId()
const formatted = ref<string>('')
const illegal = ref<boolean>(false)
const relevance = ref<number>(0)
const lines = computed(() => toValue(text).split('\n').length)
const highlightCallback = (payload: FormattedMessagePayload): void => {
formatted.value = payload.formatted
illegal.value = payload.illegal
relevance.value = payload.relevance
}
callbacks.set(id, highlightCallback)
watchEffect(() => {
const message: UnformattedMessagePayload = {
id,
text: toValue(text),
lang: toValue(language),
}
worker.postMessage(message)
})
onScopeDispose(() => callbacks.delete(id))
return { formatted, illegal, relevance, lines }
}