51 lines
1.3 KiB
TypeScript
51 lines
1.3 KiB
TypeScript
import { type TemplateResult, noChange } from 'lit';
|
|
import { AsyncDirective, directive } from 'lit/async-directive.js';
|
|
|
|
class ResolveDirective extends AsyncDirective {
|
|
promise: Promise<unknown> | undefined;
|
|
hasPromiseSettled: boolean = false;
|
|
|
|
render(promise: Promise<unknown>) {
|
|
if (this.promise !== promise) {
|
|
this.promise = promise;
|
|
|
|
if (this.isConnected) {
|
|
this.handlePromise(promise);
|
|
}
|
|
}
|
|
|
|
return noChange;
|
|
}
|
|
|
|
handlePromise(promise: Promise<unknown>) {
|
|
this.hasPromiseSettled = false;
|
|
|
|
promise.then((value) => {
|
|
if (this.promise === promise && !this.hasPromiseSettled) {
|
|
this.setValue(value);
|
|
this.hasPromiseSettled = true;
|
|
}
|
|
}).catch((error) => {
|
|
if (this.promise === promise && !this.hasPromiseSettled) {
|
|
this.setValue(error);
|
|
this.hasPromiseSettled = true;
|
|
}
|
|
});
|
|
}
|
|
|
|
disconnected() {
|
|
this.hasPromiseSettled = true; // prevent setting value if the promise settles after disconnection
|
|
}
|
|
|
|
reconnected() {
|
|
if (!this.hasPromiseSettled) {
|
|
this.handlePromise(this.promise!);
|
|
}
|
|
}
|
|
}
|
|
|
|
export const resolve = directive(ResolveDirective);
|
|
export const resolveExec = (funcArg: () => Promise<TemplateResult | unknown>) => {
|
|
return resolve(funcArg());
|
|
}
|