@mdfriday/foundry
Version:
The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.
147 lines • 5.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Executor = void 0;
exports.newExecutor = newExecutor;
const type_1 = require("../type");
/**
* Executor entity for executing templates
* TypeScript version of Go's Executor struct
*/
class Executor {
/**
* Execute template with data
*/
async execute(tmpl, data) {
try {
const [result, execErr] = await tmpl.Execute(data);
if (execErr) {
throw new type_1.TemplateError(`Template execution failed: ${execErr.message}`, 'EXECUTION_FAILED');
}
return result;
}
catch (error) {
if (error instanceof type_1.TemplateError) {
throw error;
}
const message = error instanceof Error ? error.message : String(error);
throw new type_1.TemplateError(`Template execution failed: ${message}`, 'EXECUTION_FAILED');
}
}
/**
* Execute template with timeout
*/
async executeWithTimeout(tmpl, data, timeoutMs) {
return new Promise(async (resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(new type_1.TemplateError('Template execution timeout', 'EXECUTION_TIMEOUT'));
}, timeoutMs);
await this.execute(tmpl, data)
.then(result => {
clearTimeout(timeoutId);
resolve(result);
})
.catch(error => {
clearTimeout(timeoutId);
reject(error);
});
});
}
/**
* Execute template safely with error handling
*/
async executeSafely(tmpl, data) {
try {
const result = await this.execute(tmpl, data);
return { result, error: null };
}
catch (error) {
if (error instanceof type_1.TemplateError) {
return { result: null, error };
}
const message = error instanceof Error ? error.message : String(error);
return {
result: null,
error: new type_1.TemplateError(`Execution failed: ${message}`, 'EXECUTION_ERROR')
};
}
}
/**
* Execute multiple templates in batch
*/
async executeBatch(templates) {
const results = await Promise.allSettled(templates.map(async ({ name, template, data }) => {
try {
const result = await this.execute(template, data);
return { name, result, error: null };
}
catch (error) {
return {
name,
result: null,
error: error instanceof type_1.TemplateError
? error
: new type_1.TemplateError(`Batch execution failed: ${error.message}`, 'BATCH_EXECUTION_FAILED')
};
}
}));
return results.map(result => {
if (result.status === 'fulfilled') {
return result.value;
}
else {
return {
name: 'unknown',
result: null,
error: new type_1.TemplateError(`Batch execution failed: ${result.reason}`, 'BATCH_EXECUTION_FAILED')
};
}
});
}
/**
* Execute template with context and cancellation support
*/
async executeWithContext(tmpl, data, context) {
// Check if already cancelled
if (context.signal?.aborted) {
throw new type_1.TemplateError('Template execution was cancelled', 'EXECUTION_CANCELLED');
}
// Set up cancellation listener
const cancellationPromise = new Promise((_, reject) => {
if (context.signal) {
context.signal.addEventListener('abort', () => {
reject(new type_1.TemplateError('Template execution was cancelled', 'EXECUTION_CANCELLED'));
});
}
});
// Set up timeout if specified
const timeoutPromise = context.timeout
? new Promise((_, reject) => {
setTimeout(() => {
reject(new type_1.TemplateError('Template execution timeout', 'EXECUTION_TIMEOUT'));
}, context.timeout);
})
: new Promise(() => { }); // Never resolves
// Race between execution, cancellation, and timeout
try {
return await Promise.race([
this.execute(tmpl, data),
cancellationPromise,
timeoutPromise
]);
}
catch (error) {
if (error instanceof type_1.TemplateError) {
throw error;
}
throw new type_1.TemplateError(`Context execution failed: ${error.message}`, 'CONTEXT_EXECUTION_FAILED');
}
}
}
exports.Executor = Executor;
/**
* Create a new Executor instance
*/
function newExecutor() {
return new Executor();
}
//# sourceMappingURL=executor.js.map