New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@lit-labs/task

Package Overview
Dependencies
Maintainers
8
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lit-labs/task - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

CHANGELOG.md

53

development/task.d.ts
import { ReactiveControllerHost } from '@lit/reactive-element/reactive-controller.js';
export declare type TaskFunction<D extends [...unknown[]], R = any> = (args: D) => R | typeof initialState | Promise<R | typeof initialState>;
export declare type DepsFunction<D extends [...unknown[]]> = () => D;
export declare type ArgsFunction<D extends [...unknown[]]> = () => D;
export { ArgsFunction as DepsFunction };
/**

@@ -25,2 +26,7 @@ * States for task status

};
export interface TaskConfig<T extends unknown[], R> {
task: TaskFunction<T, R>;
args?: ArgsFunction<T>;
autoRun?: boolean;
}
/**

@@ -38,2 +44,6 @@ * A controller that performs an asynchronous task like a fetch when its host

*
* The task is run automatically when its arguments change; however, this can
* be customized by setting `autoRun` to false and calling `run` explicitly
* to run the task.
*
* class MyElement extends ReactiveElement {

@@ -43,6 +53,7 @@ * url = 'example.com/api';

* task = new Task(
* this,
* ([url, id]) =>
* fetch(`${this.url}?id=${this.id}`).then(response => response.json()),
* () => [this.id, this.url]
* this, {
* task: ([url, id]) =>
* fetch(`${this.url}?id=${this.id}`).then(response => response.json()),
* args: () => [this.id, this.url]
* }
* );

@@ -60,5 +71,5 @@ *

export declare class Task<T extends [...unknown[]] = any, R = any> {
private _previousDeps;
private _previousArgs?;
private _task;
private _getDependencies;
private _getArgs?;
private _callId;

@@ -76,12 +87,34 @@ private _host;

taskComplete: Promise<R>;
/**
* Controls if they task will run when its arguments change. Defaults to true.
*/
autoRun: boolean;
private _resolveTaskComplete;
private _rejectTaskComplete;
constructor(host: ReactiveControllerHost, task: TaskFunction<T, R>, getDependencies: DepsFunction<T>);
constructor(host: ReactiveControllerHost, task: TaskFunction<T, R>, args?: ArgsFunction<T>);
constructor(host: ReactiveControllerHost, task: TaskConfig<T, R>);
hostUpdated(): void;
private _completeTask;
protected performTask(): Promise<void>;
/**
* Determines if the task should run when it's triggered as part of the
* host's reactive lifecycle. Note, this is not checked when `run` is
* explicitly called. A task runs automatically when `autoRun` is `true` and
* either its arguments change.
* @param args The task's arguments
* @returns
*/
protected shouldRun(args?: T): boolean;
/**
* A task runs when its arguments change, as long as the `autoRun` option
* has not been set to false. To explicitly run a task outside of these
* conditions, call `run`. A custom set of arguments can optionally be passed
* and if not given, the configured arguments are used.
* @param args optional set of arguments to use for this task run
*/
run(args?: T): Promise<void>;
get value(): R | undefined;
get error(): unknown;
render(renderer: StatusRenderer<R>): unknown;
private _isDirty;
private _argsDirty;
}
//# sourceMappingURL=task.d.ts.map

149

development/task.js

@@ -48,2 +48,6 @@ /**

*
* The task is run automatically when its arguments change; however, this can
* be customized by setting `autoRun` to false and calling `run` explicitly
* to run the task.
*
* class MyElement extends ReactiveElement {

@@ -53,6 +57,7 @@ * url = 'example.com/api';

* task = new Task(
* this,
* ([url, id]) =>
* fetch(`${this.url}?id=${this.id}`).then(response => response.json()),
* () => [this.id, this.url]
* this, {
* task: ([url, id]) =>
* fetch(`${this.url}?id=${this.id}`).then(response => response.json()),
* args: () => [this.id, this.url]
* }
* );

@@ -71,10 +76,17 @@ *

export class Task {
constructor(host, task, getDependencies) {
this._previousDeps = [];
constructor(host, task, args) {
this._callId = 0;
this.status = TaskStatus.INITIAL;
/**
* Controls if they task will run when its arguments change. Defaults to true.
*/
this.autoRun = true;
this._host = host;
this._host.addController(this);
this._task = task;
this._getDependencies = getDependencies;
const taskConfig = typeof task === 'object' ? task : { task, args };
this._task = taskConfig.task;
this._getArgs = taskConfig.args;
if (taskConfig.autoRun !== undefined) {
this.autoRun = taskConfig.autoRun;
}
this.taskComplete = new Promise((res, rej) => {

@@ -86,48 +98,72 @@ this._resolveTaskComplete = res;

hostUpdated() {
this._completeTask();
this.performTask();
}
async _completeTask() {
const deps = this._getDependencies();
if (this._isDirty(deps)) {
if (this.status === TaskStatus.COMPLETE ||
this.status === TaskStatus.ERROR) {
this.taskComplete = new Promise((res, rej) => {
this._resolveTaskComplete = res;
this._rejectTaskComplete = rej;
});
async performTask() {
var _a;
const args = (_a = this._getArgs) === null || _a === void 0 ? void 0 : _a.call(this);
if (this.shouldRun(args)) {
this.run(args);
}
}
/**
* Determines if the task should run when it's triggered as part of the
* host's reactive lifecycle. Note, this is not checked when `run` is
* explicitly called. A task runs automatically when `autoRun` is `true` and
* either its arguments change.
* @param args The task's arguments
* @returns
*/
shouldRun(args) {
return this.autoRun && this._argsDirty(args);
}
/**
* A task runs when its arguments change, as long as the `autoRun` option
* has not been set to false. To explicitly run a task outside of these
* conditions, call `run`. A custom set of arguments can optionally be passed
* and if not given, the configured arguments are used.
* @param args optional set of arguments to use for this task run
*/
async run(args) {
var _a;
args !== null && args !== void 0 ? args : (args = (_a = this._getArgs) === null || _a === void 0 ? void 0 : _a.call(this));
if (this.status === TaskStatus.COMPLETE ||
this.status === TaskStatus.ERROR) {
this.taskComplete = new Promise((res, rej) => {
this._resolveTaskComplete = res;
this._rejectTaskComplete = rej;
});
}
this.status = TaskStatus.PENDING;
this._error = undefined;
this._value = undefined;
let result;
let error;
// Request an update to report pending state.
this._host.requestUpdate();
const key = ++this._callId;
try {
result = await this._task(args);
}
catch (e) {
error = e;
}
// If this is the most recent task call, process this value.
if (this._callId === key) {
if (result === initialState) {
this.status = TaskStatus.INITIAL;
}
this.status = TaskStatus.PENDING;
this._error = undefined;
this._value = undefined;
let result;
let error;
// Request an update to report pending state.
this._host.requestUpdate();
const key = ++this._callId;
try {
result = await this._task(deps);
}
catch (e) {
error = e;
}
// If this is the most recent task call, process this value.
if (this._callId === key) {
if (result === initialState) {
this.status = TaskStatus.INITIAL;
else {
if (error === undefined) {
this.status = TaskStatus.COMPLETE;
this._resolveTaskComplete(result);
}
else {
if (error === undefined) {
this.status = TaskStatus.COMPLETE;
this._resolveTaskComplete(result);
}
else {
this.status = TaskStatus.ERROR;
this._rejectTaskComplete(error);
}
this._value = result;
this._error = error;
this.status = TaskStatus.ERROR;
this._rejectTaskComplete(error);
}
// Request an update with the final value.
this._host.requestUpdate();
this._value = result;
this._error = error;
}
// Request an update with the final value.
this._host.requestUpdate();
}

@@ -157,15 +193,10 @@ }

}
_isDirty(deps) {
let i = 0;
const previousDeps = this._previousDeps;
this._previousDeps = deps;
for (const dep of deps) {
if (notEqual(dep, previousDeps[i])) {
return true;
}
i++;
}
return false;
_argsDirty(args) {
const prev = this._previousArgs;
this._previousArgs = args;
return Array.isArray(args) && Array.isArray(prev)
? args.length === prev.length && args.some((v, i) => notEqual(v, prev[i]))
: args !== prev;
}
}
//# sourceMappingURL=task.js.map
{
"name": "@lit-labs/task",
"version": "1.0.0",
"version": "1.1.0",
"description": "A controller for Lit that renders asynchronous tasks.",

@@ -64,3 +64,3 @@ "license": "BSD-3-Clause",

"dependencies": {
"@lit/reactive-element": "^1.0.0"
"@lit/reactive-element": "^1.1.0"
},

@@ -67,0 +67,0 @@ "publishConfig": {

@@ -11,5 +11,17 @@ # @lit-labs/task

easily reusable way. The controller integrates with a host Lit element. The
user provides a task function and a dependencies function. Whenever the element
updates, the dependencies are checked and if any have changed, the task is
initiated. The controller requests an update of the element whenever the task
user provides a task function and an arguments function. Whenever the element
updates, the arguments are checked and if any have changed, the task is
initiated.
Sometimes it's important to control exactly when a task runs. For example,
task arguments may have changed, but it should not run until an interaction
event like a button click. For these types of use cases, the `autoRun` option
can be set to `false`. This setting can be passed in the task configuration
and/or be set on the `Task` itself. It defaults to `true`, but when `autoRun`
is `false`, the task does not run automatically when arguments change.
Instead, it can be run explicitly by calling `run(arg?)`. By default, `run()`
uses the task's configured arguments function, but a custom array of arguments
may be optionally passed.
The controller requests an update of the element whenever the task
status changes. Task status is provided via the `TaskStatus` object which has

@@ -21,3 +33,3 @@ values for `INITIAL`, `PENDING`, `COMPLETE`, and `ERROR`. The task result is

`initial`, `pending`, `complete(value)`, and `error(error)`. These methods
typically return a Lit `TemplateResult` to render
typically return a Lit `TemplateResult` to render.

@@ -57,4 +69,4 @@ ## Installation

${this._apiTask.render({
pending: html`Loading user info...`;
complete(user): html`${user.name}`;
pending: () => html`Loading user info...`,
complete: (user) => html`${user.name}`
})}

@@ -61,0 +73,0 @@ <!-- ... -->

import { ReactiveControllerHost } from '@lit/reactive-element/reactive-controller.js';
export declare type TaskFunction<D extends [...unknown[]], R = any> = (args: D) => R | typeof initialState | Promise<R | typeof initialState>;
export declare type DepsFunction<D extends [...unknown[]]> = () => D;
export declare type ArgsFunction<D extends [...unknown[]]> = () => D;
export { ArgsFunction as DepsFunction };
/**

@@ -25,2 +26,7 @@ * States for task status

};
export interface TaskConfig<T extends unknown[], R> {
task: TaskFunction<T, R>;
args?: ArgsFunction<T>;
autoRun?: boolean;
}
/**

@@ -38,2 +44,6 @@ * A controller that performs an asynchronous task like a fetch when its host

*
* The task is run automatically when its arguments change; however, this can
* be customized by setting `autoRun` to false and calling `run` explicitly
* to run the task.
*
* class MyElement extends ReactiveElement {

@@ -43,6 +53,7 @@ * url = 'example.com/api';

* task = new Task(
* this,
* ([url, id]) =>
* fetch(`${this.url}?id=${this.id}`).then(response => response.json()),
* () => [this.id, this.url]
* this, {
* task: ([url, id]) =>
* fetch(`${this.url}?id=${this.id}`).then(response => response.json()),
* args: () => [this.id, this.url]
* }
* );

@@ -60,5 +71,5 @@ *

export declare class Task<T extends [...unknown[]] = any, R = any> {
private _previousDeps;
private _previousArgs?;
private _task;
private _getDependencies;
private _getArgs?;
private _callId;

@@ -76,12 +87,34 @@ private _host;

taskComplete: Promise<R>;
/**
* Controls if they task will run when its arguments change. Defaults to true.
*/
autoRun: boolean;
private _resolveTaskComplete;
private _rejectTaskComplete;
constructor(host: ReactiveControllerHost, task: TaskFunction<T, R>, getDependencies: DepsFunction<T>);
constructor(host: ReactiveControllerHost, task: TaskFunction<T, R>, args?: ArgsFunction<T>);
constructor(host: ReactiveControllerHost, task: TaskConfig<T, R>);
hostUpdated(): void;
private _completeTask;
protected performTask(): Promise<void>;
/**
* Determines if the task should run when it's triggered as part of the
* host's reactive lifecycle. Note, this is not checked when `run` is
* explicitly called. A task runs automatically when `autoRun` is `true` and
* either its arguments change.
* @param args The task's arguments
* @returns
*/
protected shouldRun(args?: T): boolean;
/**
* A task runs when its arguments change, as long as the `autoRun` option
* has not been set to false. To explicitly run a task outside of these
* conditions, call `run`. A custom set of arguments can optionally be passed
* and if not given, the configured arguments are used.
* @param args optional set of arguments to use for this task run
*/
run(args?: T): Promise<void>;
get value(): R | undefined;
get error(): unknown;
render(renderer: StatusRenderer<R>): unknown;
private _isDirty;
private _argsDirty;
}
//# sourceMappingURL=task.d.ts.map

@@ -6,3 +6,3 @@ import{notEqual as t}from"@lit/reactive-element";

* SPDX-License-Identifier: BSD-3-Clause
*/const i={INITIAL:0,PENDING:1,COMPLETE:2,ERROR:3},s=Symbol();class h{constructor(t,i,s){this.t=[],this.i=0,this.status=0,this.h=t,this.h.addController(this),this.o=i,this.l=s,this.taskComplete=new Promise(((t,i)=>{this.u=t,this.v=i}))}hostUpdated(){this.m()}async m(){const t=this.l();if(this.p(t)){let i,h;2!==this.status&&3!==this.status||(this.taskComplete=new Promise(((t,i)=>{this.u=t,this.v=i}))),this.status=1,this.I=void 0,this.P=void 0,this.h.requestUpdate();const e=++this.i;try{i=await this.o(t)}catch(t){h=t}this.i===e&&(i===s?this.status=0:(void 0===h?(this.status=2,this.u(i)):(this.status=3,this.v(h)),this.P=i,this.I=h),this.h.requestUpdate())}}get value(){return this.P}get error(){return this.I}render(t){var i,s,h,e;switch(this.status){case 0:return null===(i=t.initial)||void 0===i?void 0:i.call(t);case 1:return null===(s=t.pending)||void 0===s?void 0:s.call(t);case 2:return null===(h=t.complete)||void 0===h?void 0:h.call(t,this.value);case 3:return null===(e=t.error)||void 0===e?void 0:e.call(t,this.error);default:this.status}}p(i){let s=0;const h=this.t;this.t=i;for(const e of i){if(t(e,h[s]))return!0;s++}return!1}}export{h as Task,i as TaskStatus,s as initialState};
*/const i={INITIAL:0,PENDING:1,COMPLETE:2,ERROR:3},s=Symbol();class h{constructor(t,i,s){this.t=0,this.status=0,this.autoRun=!0,this.i=t,this.i.addController(this);const h="object"==typeof i?i:{task:i,args:s};this.h=h.task,this.o=h.args,void 0!==h.autoRun&&(this.autoRun=h.autoRun),this.taskComplete=new Promise(((t,i)=>{this.l=t,this.u=i}))}hostUpdated(){this.performTask()}async performTask(){var t;const i=null===(t=this.o)||void 0===t?void 0:t.call(this);this.shouldRun(i)&&this.run(i)}shouldRun(t){return this.autoRun&&this.v(t)}async run(t){var i;let h,r;null!=t||(t=null===(i=this.o)||void 0===i?void 0:i.call(this)),2!==this.status&&3!==this.status||(this.taskComplete=new Promise(((t,i)=>{this.l=t,this.u=i}))),this.status=1,this.m=void 0,this.p=void 0,this.i.requestUpdate();const o=++this.t;try{h=await this.h(t)}catch(t){r=t}this.t===o&&(h===s?this.status=0:(void 0===r?(this.status=2,this.l(h)):(this.status=3,this.u(r)),this.p=h,this.m=r),this.i.requestUpdate())}get value(){return this.p}get error(){return this.m}render(t){var i,s,h,r;switch(this.status){case 0:return null===(i=t.initial)||void 0===i?void 0:i.call(t);case 1:return null===(s=t.pending)||void 0===s?void 0:s.call(t);case 2:return null===(h=t.complete)||void 0===h?void 0:h.call(t,this.value);case 3:return null===(r=t.error)||void 0===r?void 0:r.call(t,this.error);default:this.status}}v(i){const s=this.g;return this.g=i,Array.isArray(i)&&Array.isArray(s)?i.length===s.length&&i.some(((i,h)=>t(i,s[h]))):i!==s}}export{h as Task,i as TaskStatus,s as initialState};
//# sourceMappingURL=task.js.map

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc