@beignet/core
Version:
Core framework primitives for Beignet
115 lines • 3.06 kB
JavaScript
import { runWithResolvedTracingContext } from "../tracing/execution.js";
/**
* Error thrown when task input validation fails.
*/
export class TaskValidationError extends Error {
/**
* Raw Standard Schema validation issues.
*/
issues;
constructor(args) {
super(`Task "${args.name}" input validation failed: ${formatIssues(args.issues)}`);
this.name = "TaskValidationError";
this.issues = args.issues;
}
}
function formatPath(path) {
if (!path || path.length === 0)
return "";
return path
.map((segment) => {
if (typeof segment === "number")
return `[${segment}]`;
const key = String(segment);
return /^[A-Za-z_$][\w$]*$/.test(key)
? `.${key}`
: `[${JSON.stringify(key)}]`;
})
.join("")
.replace(/^\./, "");
}
function formatIssues(issues) {
return issues
.map((issue) => {
const path = formatPath(issue.path);
return path ? `${path}: ${issue.message}` : issue.message;
})
.join("; ");
}
async function parseInput(schema, input, options) {
const result = await schema["~standard"].validate(input);
if (result.issues?.length) {
throw new TaskValidationError({
name: options.name,
issues: result.issues,
});
}
return result.value;
}
function defineTaskImpl(name, options) {
return {
kind: "task",
name,
input: options.input,
description: options.description,
handle: options.handle,
};
}
/**
* Validate and parse a task input with the task's Standard Schema.
*/
export async function parseTaskInput(task, input) {
return (await parseInput(task.input, input, {
name: task.name,
}));
}
/**
* Parse input and run an operational task.
*/
export async function runTask(task, options) {
const traceAttributes = {
"beignet.task.name": task.name,
};
return await runWithResolvedTracingContext({
tracing: options.tracing,
ctx: options.ctx,
operation: {
name: `beignet.task ${task.name}`,
type: "task",
kind: "internal",
attributes: traceAttributes,
metricAttributes: traceAttributes,
},
run: async (ctx) => {
const parsed = await parseTaskInput(task, options.input);
return (await task.handle({
task,
input: parsed,
ctx,
}));
},
});
}
/**
* Define a task registry while preserving tuple inference.
*/
export function defineTasks(tasks) {
return tasks;
}
/**
* Create task helper methods bound to an application context type.
*
* Call it once in `lib/tasks.ts`:
*
* ```ts
* export const { defineTask } = createTasks<AppContext>();
* ```
*/
export function createTasks() {
return {
defineTask(name, options) {
return defineTaskImpl(name, options);
},
};
}
//# sourceMappingURL=index.js.map