diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/content-function.js | 4 | ||||
-rw-r--r-- | src/content/dependencies/index.js | 89 |
2 files changed, 82 insertions, 11 deletions
diff --git a/src/content-function.js b/src/content-function.js index dbac691b..0a217800 100644 --- a/src/content-function.js +++ b/src/content-function.js @@ -383,6 +383,7 @@ export function quickEvaluate({ // provided as part of allContentDependencies or allExtraDependencies. // Catch and report these early, together in an aggregate error. const unfulfilledErrors = []; + const unfulfilledNames = []; for (const name of neededContentDependencyNames) { const contentFunction = fulfilledContentDependencies[name]; if (!contentFunction) continue; @@ -392,12 +393,13 @@ export function quickEvaluate({ } catch (error) { error.message = `(${name}) ${error.message}`; unfulfilledErrors.push(error); + unfulfilledNames.push(name); } } } if (!empty(unfulfilledErrors)) { - throw new AggregateError(unfulfilledErrors, `Content functions unfulfilled`); + throw new AggregateError(unfulfilledErrors, `Content functions unfulfilled (${unfulfilledNames.join(', ')})`); } const slotResults = {}; diff --git a/src/content/dependencies/index.js b/src/content/dependencies/index.js index 5cd116d4..7f86abb1 100644 --- a/src/content/dependencies/index.js +++ b/src/content/dependencies/index.js @@ -7,12 +7,19 @@ import contentFunction from '../../content-function.js'; import {color, logWarn} from '../../util/cli.js'; import {annotateFunction} from '../../util/sugar.js'; -export function watchContentDependencies() { +export function watchContentDependencies({ + logging = true, +} = {}) { const events = new EventEmitter(); const contentDependencies = {}; + let emittedReady = false; + let initialScanComplete = false; + let allDependenciesFulfilled = false; + Object.assign(events, { contentDependencies, + close, }); // Watch adjacent files @@ -32,10 +39,42 @@ export function watchContentDependencies() { return; } handlePathRemoved(filePath); - }) + }); + + watcher.on('ready', () => { + initialScanComplete = true; + checkReadyConditions(); + }); return events; + async function close() { + return watcher.close(); + } + + function checkReadyConditions() { + if (emittedReady) { + return; + } + + if (!initialScanComplete) { + return; + } + + checkAllDependenciesFulfilled(); + + if (!allDependenciesFulfilled) { + return; + } + + events.emit('ready'); + emittedReady = true; + } + + function checkAllDependenciesFulfilled() { + allDependenciesFulfilled = !Object.values(contentDependencies).includes(null); + } + function getFunctionName(filePath) { const shortPath = path.basename(filePath); const functionName = shortPath.slice(0, -path.extname(shortPath).length); @@ -85,24 +124,54 @@ export function watchContentDependencies() { } contentDependencies[functionName] = fn; + + events.emit('update', functionName); + checkReadyConditions(); } if (!error) { return true; } - if (contentDependencies[functionName]) { - logWarn`Failed to import ${functionName} - using existing version`; - } else { - logWarn`Failed to import ${functionName} - no prior version loaded`; + if (!(functionName in contentDependencies)) { + contentDependencies[functionName] = null; } - if (typeof error === 'string') { - console.error(color.yellow(error)); - } else { - console.error(error); + events.emit('error', functionName, error); + + if (logging) { + if (contentDependencies[functionName]) { + logWarn`Failed to import ${functionName} - using existing version`; + } else { + logWarn`Failed to import ${functionName} - no prior version loaded`; + } + + if (typeof error === 'string') { + console.error(color.yellow(error)); + } else { + console.error(error); + } } return false; } } + +export function quickLoadContentDependencies() { + return new Promise((resolve, reject) => { + const watcher = watchContentDependencies(); + + watcher.on('error', (name, error) => { + watcher.close().then(() => { + error.message = `Error loading dependency ${name}: ${error}`; + reject(error); + }); + }); + + watcher.on('ready', () => { + watcher.close().then(() => { + resolve(watcher.contentDependencies); + }); + }); + }); +} |