Skip to content

Commit 5f543da

Browse files
committed
fix: don't dispose in-memory files
1 parent ee814e7 commit 5f543da

File tree

3 files changed

+60
-61
lines changed

3 files changed

+60
-61
lines changed

src/editor/MonacoEditor.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defineProps<{
99
mode?: PreviewMode
1010
}>()
1111
12-
const emits = defineEmits<{
12+
const emit = defineEmits<{
1313
(e: 'change', code: string): void
1414
}>()
1515
@@ -18,7 +18,7 @@ defineOptions({
1818
})
1919
2020
const onChange = (code: string) => {
21-
emits('change', code)
21+
emit('change', code)
2222
}
2323
</script>
2424

src/monaco/Monaco.vue

Lines changed: 7 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
1-
<script lang="ts">
2-
import { loadMonacoEnv, loadWasm } from './env'
3-
4-
let init = false
5-
</script>
6-
71
<script lang="ts" setup>
82
import {
93
onMounted,
104
onBeforeUnmount,
115
ref,
126
shallowRef,
137
nextTick,
14-
watchEffect,
158
inject,
169
watch,
1710
computed,
1811
} from 'vue'
1912
import * as monaco from 'monaco-editor-core'
13+
import { initMonaco } from './env'
2014
import { getOrCreateModel } from './utils'
2115
import { loadGrammars, loadTheme } from 'monaco-volar'
2216
import { Store } from '../store'
@@ -34,46 +28,16 @@ const props = withDefaults(
3428
}
3529
)
3630
37-
const emits = defineEmits<{
31+
const emit = defineEmits<{
3832
(e: 'change', value: string): void
3933
}>()
4034
41-
const containerRef = ref<HTMLDivElement | null>()
35+
const containerRef = ref<HTMLDivElement>()
4236
const ready = ref(false)
43-
const editor = shallowRef<monaco.editor.IStandaloneCodeEditor | undefined>(
44-
undefined
45-
)
46-
const store = inject('store') as Store
37+
const editor = shallowRef<monaco.editor.IStandaloneCodeEditor>()
38+
const store = inject<Store>('store')!
4739
48-
if (!init) {
49-
init = true
50-
loadMonacoEnv(store)
51-
loadWasm()
52-
}
53-
54-
if (!props.readonly) {
55-
watchEffect(() => {
56-
// create a model for each file in the store
57-
for (const filename in store.state.files) {
58-
const file = store.state.files[filename]
59-
if (monaco.editor.getModel(monaco.Uri.parse(`file:///${filename}`)))
60-
continue
61-
getOrCreateModel(
62-
monaco.Uri.parse(`file:///${filename}`),
63-
file.language,
64-
file.code
65-
)
66-
}
67-
68-
// dispose of any models that are not in the store
69-
for (const model of monaco.editor.getModels()) {
70-
if (store.state.files[model.uri.toString().substring('file:///'.length)])
71-
continue
72-
if (model.uri.toString().startsWith('file:///node_modules/')) continue
73-
model.dispose()
74-
}
75-
})
76-
}
40+
initMonaco(store)
7741
7842
const lang = computed(() => (props.mode === 'css' ? 'css' : 'javascript'))
7943
@@ -106,22 +70,6 @@ onMounted(async () => {
10670
})
10771
editor.value = editorInstance
10872
109-
// Support for go to definition
110-
monaco.editor.registerEditorOpener({
111-
openCodeEditor(_, resource) {
112-
const path = resource.path
113-
if (/^\//.test(path) && !/^\/node_modules/.test(path)) {
114-
const fileName = path.replace('/', '')
115-
if (fileName !== store.state.activeFile.filename) {
116-
store.setActive(fileName)
117-
return true
118-
}
119-
}
120-
121-
return false
122-
},
123-
})
124-
12573
// Support for semantic highlighting
12674
const t = (editorInstance as any)._themeService._theme
12775
t.getTokenStyleMetadata = (
@@ -182,7 +130,7 @@ onMounted(async () => {
182130
})
183131
184132
editorInstance.onDidChangeModelContent(() => {
185-
emits('change', editorInstance.getValue())
133+
emit('change', editorInstance.getValue())
186134
})
187135
188136
editorInstance.onDidChangeCursorSelection((e) => {

src/monaco/env.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { watchEffect } from 'vue'
2+
import * as monaco from 'monaco-editor-core'
13
import editorWorker from 'monaco-editor-core/esm/vs/editor/editor.worker?worker'
24
import vueWorker from './vue.worker?worker'
35
import * as onigasm from 'onigasm'
@@ -8,6 +10,55 @@ import { Store } from '../store'
810
import { createJsDelivrDtsHost } from 'volar-service-typescript'
911
import { getOrCreateModel } from './utils'
1012

13+
let initted = false
14+
export function initMonaco(store: Store) {
15+
if (initted) return
16+
loadMonacoEnv(store)
17+
loadWasm()
18+
19+
watchEffect(() => {
20+
// create a model for each file in the store
21+
for (const filename in store.state.files) {
22+
const file = store.state.files[filename]
23+
if (monaco.editor.getModel(monaco.Uri.parse(`file:///${filename}`)))
24+
continue
25+
getOrCreateModel(
26+
monaco.Uri.parse(`file:///${filename}`),
27+
file.language,
28+
file.code
29+
)
30+
}
31+
32+
// dispose of any models that are not in the store
33+
for (const model of monaco.editor.getModels()) {
34+
const uri = model.uri.toString()
35+
if (store.state.files[uri.substring('file:///'.length)]) continue
36+
if (uri.startsWith('file:///node_modules/')) continue
37+
if (uri.startsWith('inmemory://')) continue
38+
39+
model.dispose()
40+
}
41+
})
42+
43+
// Support for go to definition
44+
monaco.editor.registerEditorOpener({
45+
openCodeEditor(_, resource) {
46+
const path = resource.path
47+
if (/^\//.test(path) && !/^\/node_modules/.test(path)) {
48+
const fileName = path.replace('/', '')
49+
if (fileName !== store.state.activeFile.filename) {
50+
store.setActive(fileName)
51+
return true
52+
}
53+
}
54+
55+
return false
56+
},
57+
})
58+
59+
initted = true
60+
}
61+
1162
export function loadWasm() {
1263
return onigasm.loadWASM(onigasmWasm)
1364
}

0 commit comments

Comments
 (0)