2023-09-04 14:31:56 +00:00
|
|
|
import { type TemplateResult, noChange } from 'lit';
|
2023-03-15 21:22:30 +00:00
|
|
|
import { AsyncDirective, directive } from 'lit/async-directive.js';
|
|
|
|
|
2023-03-29 18:29:12 +00:00
|
|
|
class ResolveDirective extends AsyncDirective {
|
2023-09-04 12:56:57 +00:00
|
|
|
promise: Promise<unknown> | undefined;
|
|
|
|
hasPromiseSettled: boolean = false;
|
2023-03-15 21:22:30 +00:00
|
|
|
|
2023-09-04 12:56:57 +00:00
|
|
|
render(promise: Promise<unknown>) {
|
|
|
|
if (this.promise !== promise) {
|
|
|
|
this.promise = promise;
|
2023-03-15 21:22:30 +00:00
|
|
|
|
|
|
|
if (this.isConnected) {
|
2023-09-04 12:56:57 +00:00
|
|
|
this.handlePromise(promise);
|
2023-03-15 21:22:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return noChange;
|
|
|
|
}
|
|
|
|
|
2023-09-04 12:56:57 +00:00
|
|
|
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;
|
|
|
|
}
|
2023-03-15 21:22:30 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
disconnected() {
|
2023-09-04 12:56:57 +00:00
|
|
|
this.hasPromiseSettled = true; // prevent setting value if the promise settles after disconnection
|
2023-03-15 21:22:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
reconnected() {
|
2023-09-04 12:56:57 +00:00
|
|
|
if (!this.hasPromiseSettled) {
|
|
|
|
this.handlePromise(this.promise!);
|
|
|
|
}
|
2023-03-15 21:22:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-07 07:19:53 +00:00
|
|
|
export const resolve = directive(ResolveDirective);
|
2023-09-04 14:31:56 +00:00
|
|
|
export const resolveExec = (funcArg: () => Promise<TemplateResult | unknown>) => {
|
|
|
|
return resolve(funcArg());
|
|
|
|
}
|