A controller for Lit that renders asynchronous tasks.
npx @tessl/cli install tessl/npm-lit--task@1.0.0@lit/task is a reactive controller for Lit elements that simplifies the management and rendering of asynchronous tasks such as API calls, data fetching, and remote operations. It provides automatic task execution when arguments change, manual task control, comprehensive status tracking (INITIAL, PENDING, COMPLETE, ERROR), and built-in rendering patterns for different task states.
npm install @lit/taskimport { Task, TaskStatus } from "@lit/task";For deep equality utilities:
import { deepArrayEquals, deepEquals } from "@lit/task/deep-equals.js";For direct task module access:
import { Task, TaskStatus, shallowArrayEquals, initialState } from "@lit/task/task.js";import { LitElement, html } from "lit";
import { state } from "lit/decorators.js";
import { Task, TaskStatus } from "@lit/task";
class MyElement extends LitElement {
@state()
private _userId: number = -1;
private _apiTask = new Task(
this,
async ([userId], { signal }) => {
const response = await fetch(`/api/users/${userId}`, { signal });
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
},
() => [this._userId]
);
render() {
return html`
<div>User Info</div>
${this._apiTask.render({
pending: () => html`<p>Loading user info...</p>`,
complete: (user) => html`<p>Name: ${user.name}</p>`,
error: (error) => html`<p>Error: ${error.message}</p>`
})}
`;
}
}@lit/task is built around several key components:
Task class that integrates with Lit's reactive update cycleTaskStatus constantsCore task execution and lifecycle management functionality for creating, running, and controlling asynchronous operations in Lit elements.
class Task<T extends ReadonlyArray<unknown>, R> {
constructor(host: ReactiveControllerHost, config: TaskConfig<T, R>);
constructor(
host: ReactiveControllerHost,
task: TaskFunction<T, R>,
args?: ArgsFunction<T>
);
}
interface TaskConfig<T, R> {
task: TaskFunction<T, R>;
args?: ArgsFunction<T>;
autoRun?: boolean | 'afterUpdate';
argsEqual?: (oldArgs: T, newArgs: T) => boolean;
initialValue?: R;
onComplete?: (value: R) => unknown;
onError?: (error: unknown) => unknown;
}Task status tracking and template rendering functionality for displaying different task states with appropriate UI feedback.
const TaskStatus = {
INITIAL: 0,
PENDING: 1,
COMPLETE: 2,
ERROR: 3,
} as const;
interface StatusRenderer<R> {
initial?: () => unknown;
pending?: () => unknown;
complete?: (value: R) => unknown;
error?: (error: unknown) => unknown;
}Argument comparison utilities for controlling when tasks should re-execute based on changes to their input parameters.
function shallowArrayEquals<T>(oldArgs: T, newArgs: T): boolean;
function deepArrayEquals<T>(oldArgs: T, newArgs: T): boolean;
function deepEquals(a: unknown, b: unknown): boolean;type TaskFunction<D extends ReadonlyArray<unknown>, R = unknown> = (
args: D,
options: TaskFunctionOptions
) => R | typeof initialState | Promise<R | typeof initialState>;
type ArgsFunction<D extends ReadonlyArray<unknown>> = () => D;
type DepsFunction<D extends ReadonlyArray<unknown>> = ArgsFunction<D>;
interface TaskFunctionOptions {
signal: AbortSignal;
}
type TaskStatus = (typeof TaskStatus)[keyof typeof TaskStatus];
const initialState: unique symbol;
type MaybeReturnType<F> = F extends (...args: never[]) => infer R
? R
: undefined;