Skip to content

Commit 02b148e

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

File tree

6 files changed

+99
-22
lines changed

6 files changed

+99
-22
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,
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: pkgLatestVersionUrl
157+
? String(pkgLatestVersionUrl)
158+
: undefined,
159+
typescriptLib: typescriptLib ? String(typescriptLib) : undefined,
160+
}
161+
162+
worker.postMessage(message)
143163
})
144164
await init
145165
return worker

src/monaco/resource.ts

+7-10
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,19 @@ export type CreateNpmFileSystemOptions = {
1616
pkgPath: string,
1717
) => string
1818
getPackageFileTextUrl?: (
19-
path: string,
2019
pkgName: string,
2120
pkgVersion: string | undefined,
2221
pkgPath: string,
2322
) => string
2423
}
2524

2625
const defaultUnpkgOptions: Required<CreateNpmFileSystemOptions> = {
27-
getPackageLatestVersionUrl: (pkgName: string) =>
26+
getPackageLatestVersionUrl: (pkgName) =>
2827
`https://unpkg.com/${pkgName}@latest/package.json`,
29-
getPackageDirectoryUrl: (
30-
pkgName: string,
31-
pkgVersion: string,
32-
pkgPath: string,
33-
) => `https://unpkg.com/${pkgName}@${pkgVersion}/${pkgPath}/?meta`,
34-
getPackageFileTextUrl: (path: string) => `https://unpkg.com/${path}`,
28+
getPackageDirectoryUrl: (pkgName, pkgVersion, pkgPath) =>
29+
`https://unpkg.com/${pkgName}@${pkgVersion}/${pkgPath}/?meta`,
30+
getPackageFileTextUrl: (pkgName, pkgVersion, pkgPath) =>
31+
`https://unpkg.com/${pkgName}@${pkgVersion || 'latest'}/${pkgPath}`,
3532
}
3633

3734
export function createNpmFileSystem(
@@ -235,7 +232,7 @@ export function createNpmFileSystem(
235232
return
236233
}
237234
const text = await fetchText(
238-
getPackageFileTextUrl(path, pkgName, _version, pkgFilePath),
235+
getPackageFileTextUrl(pkgName, _version, pkgFilePath),
239236
)
240237
if (text !== undefined) {
241238
onFetch?.(path, text)
@@ -317,7 +314,7 @@ export function createNpmFileSystem(
317314
version = modName.substring(modName.lastIndexOf('@') + 1)
318315
}
319316
if (!version && getPackageVersion) {
320-
getPackageVersion?.(pkgName)
317+
version = getPackageVersion?.(pkgName)
321318
}
322319
return [modName, pkgName, version, path]
323320
}

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

+26-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,20 @@ 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+
pkgName: string,
431+
pkgVersion: string | undefined,
432+
pkgPath: string,
433+
) => string
434+
}
435+
417436
export type StoreState = ToRefs<{
418437
files: Record<string, File>
419438
activeFilename: string
@@ -440,6 +459,9 @@ export type StoreState = ToRefs<{
440459
/** \{ dependencyName: version \} */
441460
dependencyVersion: Record<string, string>
442461
reloadLanguageTools?: (() => void) | undefined
462+
463+
/** Custom online resources */
464+
resourceLinks?: ResourceLinkConfigs
443465
}>
444466

445467
export interface ReplStore extends UnwrapRef<StoreState> {
@@ -463,6 +485,8 @@ export interface ReplStore extends UnwrapRef<StoreState> {
463485
deserialize(serializedState: string, checkBuiltinImportMap?: boolean): void
464486
getFiles(): Record<string, string>
465487
setFiles(newFiles: Record<string, string>, mainFile?: string): Promise<void>
488+
/** Custom online resources */
489+
resourceLinks?: ResourceLinkConfigs
466490
}
467491

468492
export type Store = Pick<
@@ -487,6 +511,7 @@ export type Store = Pick<
487511
| 'renameFile'
488512
| 'getImportMap'
489513
| 'getTsConfig'
514+
| 'resourceLinks'
490515
>
491516

492517
export class File {

0 commit comments

Comments
 (0)