73 lines
2.7 KiB
JavaScript
73 lines
2.7 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2023 Google LLC
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
import { directive } from 'lit/directive.js';
|
|
import { AsyncDirective } from 'lit/async-directive.js';
|
|
import { Signal } from 'signal-polyfill';
|
|
export class WatchDirective extends AsyncDirective {
|
|
__watch() {
|
|
if (this.__watcher !== undefined) {
|
|
return;
|
|
}
|
|
this.__computed = new Signal.Computed(() => {
|
|
var _a;
|
|
return (_a = this.__signal) === null || _a === void 0 ? void 0 : _a.get();
|
|
});
|
|
const watcher = (this.__watcher = new Signal.subtle.Watcher(() => {
|
|
var _a;
|
|
// TODO: If we're not running inside a SignalWatcher, we can commit to
|
|
// the DOM independently.
|
|
(_a = this.__host) === null || _a === void 0 ? void 0 : _a._updateWatchDirective(this);
|
|
watcher.watch();
|
|
}));
|
|
watcher.watch(this.__computed);
|
|
}
|
|
__unwatch() {
|
|
var _a;
|
|
if (this.__watcher !== undefined) {
|
|
this.__watcher.unwatch(this.__computed);
|
|
this.__computed = undefined;
|
|
this.__watcher = undefined;
|
|
(_a = this.__host) === null || _a === void 0 ? void 0 : _a._clearWatchDirective(this);
|
|
}
|
|
}
|
|
commit() {
|
|
this.setValue(Signal.subtle.untrack(() => { var _a; return (_a = this.__computed) === null || _a === void 0 ? void 0 : _a.get(); }));
|
|
}
|
|
render(signal) {
|
|
// This would only be called if render is called directly, like in SSR.
|
|
return Signal.subtle.untrack(() => signal.get());
|
|
}
|
|
update(part, [signal]) {
|
|
var _a, _b;
|
|
(_a = this.__host) !== null && _a !== void 0 ? _a : (this.__host = (_b = part.options) === null || _b === void 0 ? void 0 : _b.host);
|
|
if (signal !== this.__signal && this.__signal !== undefined) {
|
|
// Unwatch the old signal
|
|
this.__unwatch();
|
|
}
|
|
this.__signal = signal;
|
|
this.__watch();
|
|
// We use untrack() so that the signal access is not tracked by the watcher
|
|
// created by SignalWatcher. This means that an can use both SignalWatcher
|
|
// and watch() and a signal update won't trigger a full element update if
|
|
// it's only passed to watch() and not otherwise accessed by the element.
|
|
return Signal.subtle.untrack(() => this.__computed.get());
|
|
}
|
|
disconnected() {
|
|
this.__unwatch();
|
|
}
|
|
reconnected() {
|
|
this.__watch();
|
|
}
|
|
}
|
|
/**
|
|
* Renders a signal and subscribes to it, updating the part when the signal
|
|
* changes.
|
|
*
|
|
* watch() can only be used in a reactive element that applies the
|
|
* SignalWatcher mixin.
|
|
*/
|
|
export const watch = directive(WatchDirective);
|
|
//# sourceMappingURL=watch.js.map
|