Skip to content

Commit 385b0b6

Browse files
committed
feat(store): resourceLinks to custom cdn
1 parent 7eb86c6 commit 385b0b6

File tree

5 files changed

+93
-12
lines changed

5 files changed

+93
-12
lines changed

src/monaco/env.ts

+22-2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ export interface WorkerMessage {
122122
event: 'init'
123123
tsVersion: string
124124
tsLocale?: string
125+
pkgDirUrl?: string
126+
pkgFileTextUrl?: string
127+
pkgLatestVersionUrl?: string
128+
typescriptLib?: string
125129
}
126130

127131
export function loadMonacoEnv(store: Store) {
@@ -135,11 +139,27 @@ export function loadMonacoEnv(store: Store) {
135139
resolve()
136140
}
137141
})
138-
worker.postMessage({
142+
143+
const {
144+
pkgDirUrl,
145+
pkgFileTextUrl,
146+
pkgLatestVersionUrl: pkgVersionLatestUrl,
147+
typescriptLib,
148+
} = store.resourceLinks || {}
149+
150+
const message: WorkerMessage = {
139151
event: 'init',
140152
tsVersion: store.typescriptVersion,
141153
tsLocale: store.locale,
142-
} satisfies WorkerMessage)
154+
pkgDirUrl: pkgDirUrl ? String(pkgDirUrl) : undefined,
155+
pkgFileTextUrl: pkgFileTextUrl ? String(pkgFileTextUrl) : undefined,
156+
pkgLatestVersionUrl: pkgVersionLatestUrl
157+
? String(pkgVersionLatestUrl)
158+
: undefined,
159+
typescriptLib: typescriptLib ? String(typescriptLib) : undefined,
160+
}
161+
162+
worker.postMessage(message)
143163
})
144164
await init
145165
return worker

src/monaco/vue.worker.ts

+35-3
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,35 @@ export interface CreateData {
2323
dependencies: Record<string, string>
2424
}
2525

26+
function createFunc(func?: string) {
27+
if (func && typeof func === 'string') {
28+
return Function(`return ${func}`)()
29+
}
30+
return undefined
31+
}
32+
2633
let ts: typeof import('typescript')
2734
let locale: string | undefined
35+
let resourceLinks: Record<
36+
keyof Pick<
37+
WorkerMessage,
38+
'pkgDirUrl' | 'pkgFileTextUrl' | 'pkgLatestVersionUrl'
39+
>,
40+
((...args: any[]) => string) | undefined
41+
>
2842

2943
self.onmessage = async (msg: MessageEvent<WorkerMessage>) => {
3044
if (msg.data?.event === 'init') {
3145
locale = msg.data.tsLocale
32-
ts = await importTsFromCdn(msg.data.tsVersion)
46+
ts = await importTsFromCdn(
47+
msg.data.tsVersion,
48+
createFunc(msg.data.typescriptLib),
49+
)
50+
resourceLinks = {
51+
pkgDirUrl: createFunc(msg.data.pkgDirUrl),
52+
pkgFileTextUrl: createFunc(msg.data.pkgFileTextUrl),
53+
pkgLatestVersionUrl: createFunc(msg.data.pkgLatestVersionUrl),
54+
}
3355
self.postMessage('inited')
3456
return
3557
}
@@ -61,6 +83,11 @@ self.onmessage = async (msg: MessageEvent<WorkerMessage>) => {
6183
content,
6284
)
6385
},
86+
{
87+
getPackageDirectoryUrl: resourceLinks.pkgDirUrl,
88+
getPackageFileTextUrl: resourceLinks.pkgFileTextUrl,
89+
getPackageLatestVersionUrl: resourceLinks.pkgLatestVersionUrl,
90+
},
6491
),
6592
}
6693

@@ -98,10 +125,15 @@ self.onmessage = async (msg: MessageEvent<WorkerMessage>) => {
98125
)
99126
}
100127

101-
async function importTsFromCdn(tsVersion: string) {
128+
async function importTsFromCdn(
129+
tsVersion: string,
130+
getTsCdn?: (version?: string) => string,
131+
) {
102132
const _module = globalThis.module
103133
;(globalThis as any).module = { exports: {} }
104-
const tsUrl = `https://cdn.jsdelivr.net/npm/typescript@${tsVersion}/lib/typescript.js`
134+
const tsUrl =
135+
getTsCdn?.(tsVersion) ||
136+
`https://cdn.jsdelivr.net/npm/typescript@${tsVersion}/lib/typescript.js`
105137
await import(/* @vite-ignore */ tsUrl)
106138
const ts = globalThis.module.exports
107139
globalThis.module = _module

src/output/Sandbox.vue

+5
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ function createSandbox() {
128128
/<!--PREVIEW-OPTIONS-PLACEHOLDER-HTML-->/,
129129
previewOptions.value?.placeholderHTML || '',
130130
)
131+
.replace(
132+
/<!--ES-MODULE-SHIMS-LINK-->/,
133+
store.value.resourceLinks?.esModuleShims ||
134+
'https://cdn.jsdelivr.net/npm/[email protected]/dist/es-module-shims.wasm.js',
135+
)
131136
sandbox.srcdoc = sandboxSrc
132137
containerRef.value?.appendChild(sandbox)
133138

src/output/srcdoc.html

+4-6
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
color-scheme: dark;
77
}
88
body {
9-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
10-
Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
9+
font-family:
10+
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
11+
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
1112
}
1213
</style>
1314
<!-- PREVIEW-OPTIONS-HEAD-HTML -->
@@ -361,10 +362,7 @@
361362
</script>
362363

363364
<!-- ES Module Shims: Import maps polyfill for modules browsers without import maps support (all except Chrome 89+) -->
364-
<script
365-
async
366-
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/es-module-shims.wasm.js"
367-
></script>
365+
<script async src="<!--ES-MODULE-SHIMS-LINK-->"></script>
368366
<script type="importmap">
369367
<!--IMPORT_MAP-->
370368
</script>

src/store.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export function useStore(
4848
typescriptVersion = ref('latest'),
4949
dependencyVersion = ref(Object.create(null)),
5050
reloadLanguageTools = ref(),
51+
resourceLinks = undefined,
5152
}: Partial<StoreState> = {},
5253
serializedState?: string,
5354
): ReplStore {
@@ -92,7 +93,9 @@ export function useStore(
9293
vueVersion,
9394
async (version) => {
9495
if (version) {
95-
const compilerUrl = `https://cdn.jsdelivr.net/npm/@vue/compiler-sfc@${version}/dist/compiler-sfc.esm-browser.js`
96+
const compilerUrl =
97+
resourceLinks?.value?.vueCompilerUrl?.(version) ||
98+
`https://cdn.jsdelivr.net/npm/@vue/compiler-sfc@${version}/dist/compiler-sfc.esm-browser.js`
9699
loading.value = true
97100
compiler.value = await import(/* @vite-ignore */ compilerUrl).finally(
98101
() => (loading.value = false),
@@ -389,6 +392,8 @@ export function useStore(
389392
deserialize,
390393
getFiles,
391394
setFiles,
395+
396+
resourceLinks,
392397
})
393398
return store
394399
}
@@ -414,6 +419,21 @@ export interface SFCOptions {
414419
template?: Partial<SFCTemplateCompileOptions>
415420
}
416421

422+
export type ResourceLinkConfigs = {
423+
esModuleShims?: string
424+
vueCompilerUrl?: (version: string) => string
425+
typescriptLib?: (version: string) => string
426+
// for monaco
427+
pkgLatestVersionUrl?: (pkgName: string) => string
428+
pkgDirUrl?: (pkgName: string, pkgVersion: string, pkgPath: string) => string
429+
pkgFileTextUrl?: (
430+
path: string,
431+
pkgName: string,
432+
pkgVersion: string | undefined,
433+
pkgPath: string,
434+
) => string
435+
}
436+
417437
export type StoreState = ToRefs<{
418438
files: Record<string, File>
419439
activeFilename: string
@@ -440,6 +460,9 @@ export type StoreState = ToRefs<{
440460
/** \{ dependencyName: version \} */
441461
dependencyVersion: Record<string, string>
442462
reloadLanguageTools?: (() => void) | undefined
463+
464+
/** Custom online resources */
465+
resourceLinks?: ResourceLinkConfigs
443466
}>
444467

445468
export interface ReplStore extends UnwrapRef<StoreState> {
@@ -463,6 +486,8 @@ export interface ReplStore extends UnwrapRef<StoreState> {
463486
deserialize(serializedState: string, checkBuiltinImportMap?: boolean): void
464487
getFiles(): Record<string, string>
465488
setFiles(newFiles: Record<string, string>, mainFile?: string): Promise<void>
489+
/** Custom online resources */
490+
resourceLinks?: ResourceLinkConfigs
466491
}
467492

468493
export type Store = Pick<
@@ -487,6 +512,7 @@ export type Store = Pick<
487512
| 'renameFile'
488513
| 'getImportMap'
489514
| 'getTsConfig'
515+
| 'resourceLinks'
490516
>
491517

492518
export class File {

0 commit comments

Comments
 (0)