@lit-labs/task
Advanced tools
Comparing version
@@ -20,2 +20,15 @@ # Change Log | ||
## 1.0.0-pre.2 - 2021-03-31 | ||
### Changed | ||
- Added result and dependency type arguments to Task | ||
### Added | ||
- Added an `initialState` sentinal value that task functions can return to reset the task state to INITIAL. | ||
<!-- ### Removed --> | ||
<!-- ### Fixed --> | ||
## [1.0.0-pre.1] - 2021-02-11 | ||
@@ -25,2 +38,2 @@ | ||
- Adds `Task` controller which can be used to perform tasks when a host element updates. When the task completes, an update is requested on the host element and the task value can be used as desired ([#1489](https://github.com/Polymer/lit-html/pulls/1489)). | ||
- Adds `Task` controller which can be used to perform tasks when a host element updates. When the task completes, an update is requested on the host element and the task value can be used as desired ([#1489](https://github.com/Polymer/lit-html/pulls/1489)). |
/** | ||
* @license | ||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
* Copyright 2017 Google LLC | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
export * from './task.js'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,2 +0,2 @@ | ||
export{Task,TaskStatus}from"./task.js"; | ||
export{Task,TaskStatus,initialState}from"./task.js"; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@lit-labs/task", | ||
"version": "1.0.0-pre.1", | ||
"version": "1.0.0-pre.2", | ||
"description": "A controller for Lit that renders asynchronous tasks.", | ||
@@ -28,7 +28,8 @@ "license": "BSD-3-Clause", | ||
"scripts": { | ||
"build": "npm run clean && tsc --build && rollup -c", | ||
"build": "npm run clean && npm run build:ts --build && rollup -c", | ||
"build:watch": "rollup -c --watch", | ||
"build:ts": "tsc --build && treemirror development . '**/*.d.ts{,.map}'", | ||
"build:ts:watch": "tsc --build --watch", | ||
"clean": "rm -rf {index,task}.{js,js.map,d.ts} development/ test/ *.tsbuildinfo", | ||
"dev": "scripts/dev.sh", | ||
"build:ts": "tsc", | ||
"build:ts:watch": "tsc --watch", | ||
"test": "npm run test:dev && npm run test:prod", | ||
@@ -41,7 +42,7 @@ "test:dev": "cd ../../tests && npx wtr '../labs/task/development/**/*_test.js'", | ||
}, | ||
"author": "The Polymer Authors", | ||
"author": "Google LLC", | ||
"devDependencies": { | ||
"@esm-bundle/chai": "^4.1.5", | ||
"@types/chai": "^4.0.1", | ||
"@types/mocha": "^8.0.3", | ||
"@types/chai": "^4.0.1", | ||
"@types/trusted-types": "^1.0.1", | ||
@@ -53,6 +54,7 @@ "@web/test-runner-mocha": "^0.3.5", | ||
"rollup": "^2.28.2", | ||
"typescript": "^4.1.3" | ||
"typescript": "^4.1.3", | ||
"internal-scripts": "^1.0.0" | ||
}, | ||
"dependencies": { | ||
"@lit/reactive-element": "^1.0.0-pre.2" | ||
"@lit/reactive-element": "^1.0.0-pre.3" | ||
}, | ||
@@ -59,0 +61,0 @@ "publishConfig": { |
/** | ||
* @license | ||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
* Copyright 2017 Google LLC | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
export * from './task.js'; |
/** | ||
* @license | ||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
* Copyright 2017 Google LLC | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
@@ -17,5 +9,7 @@ import {notEqual} from '@lit/reactive-element'; | ||
export type TaskFunction = (args: Array<unknown>) => unknown; | ||
export type Deps = Array<unknown>; | ||
export type DepsFunction = () => Deps; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export type TaskFunction<D extends [...unknown[]], R = any> = ( | ||
args: D | ||
) => R | typeof initialState | Promise<R | typeof initialState>; | ||
export type DepsFunction<D extends [...unknown[]]> = () => D; | ||
@@ -32,8 +26,14 @@ /** | ||
/** | ||
* A special value that can be returned from task functions to reset the task | ||
* status to INITIAL. | ||
*/ | ||
export const initialState = Symbol(); | ||
export type TaskStatus = typeof TaskStatus[keyof typeof TaskStatus]; | ||
export type StatusRenderer = { | ||
export type StatusRenderer<R> = { | ||
initial?: () => unknown; | ||
pending?: () => unknown; | ||
complete?: (value: unknown) => unknown; | ||
complete?: (value: R) => unknown; | ||
error?: (error: unknown) => unknown; | ||
@@ -89,16 +89,27 @@ }; | ||
*/ | ||
export class Task { | ||
private _previousDeps: Deps = []; | ||
private _task: TaskFunction; | ||
private _getDependencies: DepsFunction; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export class Task<T extends [...unknown[]] = any, R = any> { | ||
private _previousDeps: T = ([] as unknown) as T; | ||
private _task: TaskFunction<T, R>; | ||
private _getDependencies: DepsFunction<T>; | ||
private _callId = 0; | ||
private _host: ReactiveControllerHost; | ||
private _value?: unknown; | ||
private _value?: R; | ||
private _error?: unknown; | ||
status: TaskStatus = TaskStatus.INITIAL; | ||
/** | ||
* A Promise that resolve when the current task run is complete. | ||
* | ||
* If a new task run is started while a previous run is pending, the Promise | ||
* is kept and only resolved when the new run is completed. | ||
*/ | ||
taskComplete!: Promise<R>; | ||
private _resolveTaskComplete!: (value: R) => void; | ||
private _rejectTaskComplete!: (e: unknown) => void; | ||
constructor( | ||
host: ReactiveControllerHost, | ||
task: TaskFunction, | ||
getDependencies: DepsFunction | ||
task: TaskFunction<T, R>, | ||
getDependencies: DepsFunction<T> | ||
) { | ||
@@ -109,2 +120,6 @@ this._host = host; | ||
this._getDependencies = getDependencies; | ||
this.taskComplete = new Promise((res, rej) => { | ||
this._resolveTaskComplete = res; | ||
this._rejectTaskComplete = rej; | ||
}); | ||
} | ||
@@ -119,6 +134,15 @@ | ||
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; | ||
}); | ||
} | ||
this.status = TaskStatus.PENDING; | ||
this._error = undefined; | ||
this._value = undefined; | ||
let value: unknown; | ||
let result!: R | typeof initialState; | ||
let error: unknown; | ||
@@ -129,3 +153,3 @@ // Request an update to report pending state. | ||
try { | ||
value = await this._task(deps); | ||
result = await this._task(deps); | ||
} catch (e) { | ||
@@ -136,6 +160,15 @@ error = e; | ||
if (this._callId === key) { | ||
this.status = | ||
error === undefined ? TaskStatus.COMPLETE : TaskStatus.ERROR; | ||
this._value = value; | ||
this._error = error; | ||
if (result === initialState) { | ||
this.status = TaskStatus.INITIAL; | ||
} else { | ||
if (error === undefined) { | ||
this.status = TaskStatus.COMPLETE; | ||
this._resolveTaskComplete(result as R); | ||
} else { | ||
this.status = TaskStatus.ERROR; | ||
this._rejectTaskComplete(error); | ||
} | ||
this._value = result as R; | ||
this._error = error; | ||
} | ||
// Request an update with the final value. | ||
@@ -155,3 +188,3 @@ this._host.requestUpdate(); | ||
render(renderer: StatusRenderer) { | ||
render(renderer: StatusRenderer<R>) { | ||
switch (this.status) { | ||
@@ -163,9 +196,12 @@ case TaskStatus.INITIAL: | ||
case TaskStatus.COMPLETE: | ||
return renderer.complete?.(this.value); | ||
return renderer.complete?.(this.value!); | ||
case TaskStatus.ERROR: | ||
return renderer.error?.(this.error); | ||
default: | ||
// exhaustiveness check | ||
this.status as void; | ||
} | ||
} | ||
private _isDirty(deps: Deps) { | ||
private _isDirty(deps: T) { | ||
let i = 0; | ||
@@ -172,0 +208,0 @@ const previousDeps = this._previousDeps; |
import { ReactiveControllerHost } from '@lit/reactive-element/reactive-controller.js'; | ||
export declare type TaskFunction = (args: Array<unknown>) => unknown; | ||
export declare type Deps = Array<unknown>; | ||
export declare type DepsFunction = () => Deps; | ||
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; | ||
/** | ||
@@ -14,7 +13,12 @@ * States for task status | ||
}; | ||
/** | ||
* A special value that can be returned from task functions to reset the task | ||
* status to INITIAL. | ||
*/ | ||
export declare const initialState: unique symbol; | ||
export declare type TaskStatus = typeof TaskStatus[keyof typeof TaskStatus]; | ||
export declare type StatusRenderer = { | ||
export declare type StatusRenderer<R> = { | ||
initial?: () => unknown; | ||
pending?: () => unknown; | ||
complete?: (value: unknown) => unknown; | ||
complete?: (value: R) => unknown; | ||
error?: (error: unknown) => unknown; | ||
@@ -53,3 +57,3 @@ }; | ||
*/ | ||
export declare class Task { | ||
export declare class Task<T extends [...unknown[]] = any, R = any> { | ||
private _previousDeps; | ||
@@ -63,10 +67,19 @@ private _task; | ||
status: TaskStatus; | ||
constructor(host: ReactiveControllerHost, task: TaskFunction, getDependencies: DepsFunction); | ||
/** | ||
* A Promise that resolve when the current task run is complete. | ||
* | ||
* If a new task run is started while a previous run is pending, the Promise | ||
* is kept and only resolved when the new run is completed. | ||
*/ | ||
taskComplete: Promise<R>; | ||
private _resolveTaskComplete; | ||
private _rejectTaskComplete; | ||
constructor(host: ReactiveControllerHost, task: TaskFunction<T, R>, getDependencies: DepsFunction<T>); | ||
hostUpdated(): void; | ||
private _completeTask; | ||
get value(): unknown; | ||
get value(): R | undefined; | ||
get error(): unknown; | ||
render(renderer: StatusRenderer): unknown; | ||
render(renderer: StatusRenderer<R>): unknown; | ||
private _isDirty; | ||
} | ||
//# sourceMappingURL=task.d.ts.map |
14
task.js
import{notEqual as t}from"@lit/reactive-element"; | ||
/** | ||
* @license | ||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
*/const s={INITIAL:0,PENDING:1,COMPLETE:2,ERROR:3};class i{constructor(t,s,i){this.t=[],this.i=0,this.status=0,this.h=t,this.h.addController(this),this.o=s,this.u=i}hostUpdated(){this.l()}async l(){const t=this.u();if(this.v(t)){let s,i;this.status=1,this.m=void 0,this.p=void 0,this.h.requestUpdate();const h=++this.i;try{s=await this.o(t)}catch(t){i=t}this.i===h&&(this.status=void 0===i?2:3,this.p=s,this.m=i,this.h.requestUpdate())}}get value(){return this.p}get error(){return this.m}render(t){switch(this.status){case 0:return t.initial?.();case 1:return t.pending?.();case 2:return t.complete?.(this.value);case 3:return t.error?.(this.error)}}v(s){let i=0;const h=this.t;this.t=s;for(const r of s){if(t(r,h[i]))return!0;i++}return!1}}export{i as Task,s as TaskStatus}; | ||
* Copyright 2017 Google LLC | ||
* 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.g=void 0,this._=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._=i,this.g=h),this.h.requestUpdate())}}get value(){return this._}get error(){return this.g}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}; | ||
//# sourceMappingURL=task.js.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
28381
18.3%14
16.67%300
9.09%11
10%