UNPKG

haunted

Version:
64 lines (63 loc) 1.75 kB
import { hook, Hook } from "./hook"; import { contextEvent } from "./symbols"; import { setEffects } from "./use-effect"; /** * @function * @template T * @param {Context<T>} context * @return {T} */ const useContext = hook(class extends Hook { Context; value; _ranEffect; _unsubscribe; constructor(id, state, _) { super(id, state); this._updater = this._updater.bind(this); this._ranEffect = false; this._unsubscribe = null; setEffects(state, this); } update(Context) { if (this.state.virtual) { throw new Error("can't be used with virtual components"); } if (this.Context !== Context) { this._subscribe(Context); this.Context = Context; } return this.value; } call() { if (!this._ranEffect) { this._ranEffect = true; if (this._unsubscribe) this._unsubscribe(); this._subscribe(this.Context); this.state.update(); } } _updater(value) { this.value = value; this.state.update(); } _subscribe(Context) { const detail = { Context, callback: this._updater }; this.state.host.dispatchEvent(new CustomEvent(contextEvent, { detail, bubbles: true, cancelable: true, composed: true, // to pass ShadowDOM boundaries })); const { unsubscribe = null, value } = detail; this.value = unsubscribe ? value : Context.defaultValue; this._unsubscribe = unsubscribe; } teardown() { if (this._unsubscribe) { this._unsubscribe(); } } }); export { useContext };