import { Event } from 'event-target-shim' /** An event fired by a context requester to signal it desires a named context. */ export class ContextEvent extends Event<'context-request'> { constructor(init: ContextEventInit) { super('context-request', { bubbles: true, composed: true }) init = Object(init) as Required> this.context = init.context } context!: Context multiple!: boolean callback!: ContextCallback> } interface ContextEventInit { context: Context multiple?: boolean callback: ContextCallback> } /** A Context object defines an optional initial value for a Context, as well as a name identifier for debugging purposes. */ export type Context = { name: string initialValue?: T } /** A helper type which can extract a Context value type from a Context type. */ export type ContextType = T extends Context ? Y : never /** A function which creates a Context value object */ export function createContext( name: string, initialValue?: T ): Readonly> { return { name, initialValue, } } /** A callback which is provided by a context requester and is called with the value satisfying the request. */ export type ContextCallback = ( value: ValueType, dispose?: () => void ) => void declare global { interface HTMLElementEventMap { /** A 'context-request' event can be emitted by any element which desires a context value to be injected by an external provider. */ 'context-request': ContextEvent } }