-
-
Notifications
You must be signed in to change notification settings - Fork 173
/
worker.ts
95 lines (80 loc) · 2.73 KB
/
worker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { fileURLToPath } from 'node:url'
import type { MessagePort } from 'node:worker_threads'
import { performance } from 'node:perf_hooks'
import { ModuleCacheMap, ViteNodeRunner } from 'vite-node/client'
import { createBirpc } from 'birpc'
import type { FetchFunction, ResolveIdFunction } from 'vite-node'
import { dirname, resolve } from 'pathe'
import pc from 'picocolors'
import type { ServerStoryFile, ServerStory, ServerRunPayload } from '@histoire/shared'
import { createDomEnv } from '../dom/env.js'
const __dirname = dirname(fileURLToPath(import.meta.url))
export interface Payload {
root: string
base: string
port: MessagePort
storyFile: ServerStoryFile
invalidates: string[]
}
export interface ReturnData {
storyData: ServerStory[]
}
const _moduleCache = new ModuleCacheMap()
let _runner: ViteNodeRunner
let _rpc: ReturnType<typeof createBirpc<{
fetchModule: FetchFunction
resolveId: ResolveIdFunction
}>>
export default async (payload: Payload): Promise<ReturnData> => {
const startTime = performance.now()
process.env.HST_COLLECT = 'true'
_rpc = createBirpc<{
fetchModule: FetchFunction
resolveId: ResolveIdFunction
}>({}, {
post: data => payload.port.postMessage(data),
on: data => payload.port.on('message', data),
})
const runner = _runner ?? (_runner = new ViteNodeRunner({
root: payload.root,
base: payload.base,
moduleCache: _moduleCache,
fetchModule (id) {
return _rpc.fetchModule(id)
},
resolveId (id, importer) {
return _rpc.resolveId(id, importer)
},
}))
// Cleanup cache
for (const file of payload.invalidates) {
_moduleCache.delete(file)
}
const { destroy: destroyDomEnv } = createDomEnv()
const el = window.document.createElement('div')
const beforeExectureTime = performance.now()
// Mount app to collect stories/variants
const { run } = (await runner.executeFile(resolve(__dirname, './run.js'))) as { run: (payload: ServerRunPayload) => Promise<any> }
const afterExectureTime = performance.now()
const storyData: ServerStory[] = []
await run({
file: payload.storyFile,
storyData,
el,
})
const afterRunTime = performance.now()
if (payload.storyFile.markdownFile) {
const el = document.createElement('div')
el.innerHTML = payload.storyFile.markdownFile.html
const text = el.textContent
storyData.forEach(s => {
s.docsText = text
})
}
destroyDomEnv()
const endTime = performance.now()
console.log(pc.dim(`${payload.storyFile.relativePath} ${Math.round(endTime - startTime)}ms (setup:${Math.round(beforeExectureTime - startTime)}ms, execute:${Math.round(afterExectureTime - beforeExectureTime)}ms, run:${Math.round(afterRunTime - afterExectureTime)}ms)`))
return {
storyData,
}
}