Skip to content

Commit 37d429b

Browse files
committed
fix: support Repl props config
1 parent f75dd09 commit 37d429b

File tree

3 files changed

+64
-45
lines changed

3 files changed

+64
-45
lines changed

playground/scenarios/basic/_meta.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
export default {
22
mainFile: 'App.vue',
3+
ReplOptions: {
4+
theme: 'dark',
5+
},
36
}

playground/src/App.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const currentScenario = computed(() => {
3030
})
3131
3232
watchEffect(() => {
33+
console.log('currentScenario', currentScenario.value)
3334
if (currentScenario.value) {
3435
const scenario = currentScenario.value
3536
store.setFiles(scenario.files, scenario.mainFile)
@@ -44,6 +45,7 @@ const replConfigs = computed(() => ({
4445
editorOptions: {
4546
autoSaveText: '💾',
4647
},
48+
...(currentScenario.value.ReplOptions || {}),
4749
}))
4850
</script>
4951

playground/vite-plugin-scenario.js

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export default function scenarioPlugin() {
129129
}
130130

131131
/**
132-
* Scan scenario directory and generate config object
132+
* Scan scenario directory and generate config object with parallel processing
133133
* @param {string} scenariosPath - Path to scenarios directory
134134
* @returns {Promise<object>} - Config object
135135
*/
@@ -154,49 +154,39 @@ async function generateConfig(scenariosPath) {
154154

155155
const dirs = await fs.promises.readdir(scenariosPath)
156156

157-
for (const dir of dirs) {
157+
// Process all scenario directories in parallel
158+
const scenarioPromises = dirs.map(async (dir) => {
158159
const scenarioPath = path.join(scenariosPath, dir)
159160
const stat = await fs.promises.stat(scenarioPath)
160161

161-
if (!stat.isDirectory()) continue
162+
if (!stat.isDirectory()) return null
162163

163164
// Read all files in the scenario
164-
const files = {}
165165
const allFiles = await fs.promises.readdir(scenarioPath)
166-
167166
let meta = { mainFile: 'main.ts' } // Default metadata
168167

169168
// Handle metadata file first to get metadata before other files
170169
const metaFile = allFiles.find((file) => file === '_meta.js')
171170
if (metaFile) {
172171
const metaFilePath = path.join(scenarioPath, metaFile)
173172
try {
174-
// Read metadata file and manually parse
175-
const metaContent = await fs.promises.readFile(metaFilePath, 'utf-8')
176-
177-
// Extract default export part
178-
// Use simple regex to match export default {...}
179-
const defaultExportMatch = metaContent.match(
180-
/export\s+default\s+({[\s\S]*?})/m,
181-
)
182-
if (defaultExportMatch && defaultExportMatch[1]) {
183-
try {
184-
// Use Function constructor to safely parse JS object
185-
// Safer than eval, but can handle JS object syntax
186-
const extractedMeta = new Function(
187-
`return ${defaultExportMatch[1]}`,
188-
)()
189-
meta = { ...meta, ...extractedMeta }
190-
console.log(
191-
`[vite-plugin-scenario] Loaded scenario metadata: ${dir}`,
192-
meta,
193-
)
194-
} catch (parseError) {
195-
console.error(
196-
`[vite-plugin-scenario] Failed to parse metadata: ${metaFilePath}`,
197-
parseError,
198-
)
199-
}
173+
// Use dynamic import to properly load the ES module
174+
// This is safer and more reliable than regex extraction
175+
// Convert to absolute path URL for dynamic import
176+
// Add timestamp to URL to bypass module cache
177+
const fileUrl = `file://${path.resolve(metaFilePath)}?t=${Date.now()}`
178+
179+
// Dynamically import the metadata module
180+
const metaModule = await import(fileUrl)
181+
182+
if (metaModule.default) {
183+
// Deep merge the metadata with defaults
184+
// This ensures all ReplOptions properties are properly merged
185+
meta = { ...(meta || {}), ...(metaModule.default || {}) }
186+
console.log(
187+
`[vite-plugin-scenario] Loaded scenario metadata: ${dir}`,
188+
meta,
189+
)
200190
}
201191
} catch (error) {
202192
console.error(
@@ -206,25 +196,49 @@ async function generateConfig(scenariosPath) {
206196
}
207197
}
208198

209-
// Process all files in the scenario
210-
for (const file of allFiles) {
211-
// Skip hidden files and metadata file
212-
if (file.startsWith('.') || file === '_meta.js') continue
213-
214-
// Read file content
215-
const filePath = path.join(scenarioPath, file)
216-
const content = await fs.promises.readFile(filePath, 'utf-8')
199+
// Read all scenario files in parallel
200+
const filePromises = allFiles
201+
.filter((file) => !file.startsWith('.') && file !== '_meta.js')
202+
.map(async (file) => {
203+
const filePath = path.join(scenarioPath, file)
204+
try {
205+
const content = await fs.promises.readFile(filePath, 'utf-8')
206+
return [file, content] // Return as key-value pair
207+
} catch (error) {
208+
console.error(
209+
`[vite-plugin-scenario] Error reading file: ${filePath}`,
210+
error,
211+
)
212+
return [file, ''] // Return empty content on error
213+
}
214+
})
217215

218-
// Store file content in config
219-
files[file] = content
220-
}
216+
// Wait for all file reading promises to complete
217+
const fileEntries = await Promise.all(filePromises)
218+
const files = Object.fromEntries(fileEntries)
221219

222-
// Build scenario config
223-
config[dir] = {
220+
// Build complete scenario configuration
221+
// Structure it to match what REPL expects: files object + options
222+
const scenarioConfig = {
223+
// Files must be in this format for REPL
224224
files,
225+
// all meta config support extend
225226
...meta,
226227
}
227-
}
228+
229+
// Return scenario name and its configuration
230+
return [dir, scenarioConfig]
231+
})
232+
233+
// Wait for all scenario processing to complete
234+
const scenarioResults = await Promise.all(scenarioPromises)
235+
236+
// Filter out null results (non-directories) and build config object
237+
scenarioResults
238+
.filter((result) => result !== null)
239+
.forEach(([scenarioName, scenarioConfig]) => {
240+
config[scenarioName] = scenarioConfig
241+
})
228242

229243
console.log(
230244
`[vite-plugin-scenario] Config generated, scenarios: ${Object.keys(config).join(', ')}`,

0 commit comments

Comments
 (0)