UNPKG

context-protocol

Version:

A fully-typed implementation of the context-protocol, with support for subscriptions.

1 lines 1.7 kB
import{ContextRequestEvent,createContext}from"./context.js";var addContextListener=(consumer,context,callback,subscribe)=>{consumer.dispatchEvent(new ContextRequestEvent(context,callback,subscribe))},removeContextListener=(consumer,context,callback)=>{UPSERT_INVOKERS_BY_CONSUMER_AND_CONTEXT(consumer,context).delete(callback)},setContextValue=(provider,context,value)=>{let consumers=UPSERT(CONSUMERS_BY_PROVIDER,provider,()=>{return provider.addEventListener("context-request",(event)=>{if(event.context!==context)return;event.stopImmediatePropagation();let callbacks=UPSERT_INVOKERS_BY_CONSUMER_AND_CONTEXT(event.target,context);if(event.subscribe){if(consumers.add(event.target),callbacks.size<callbacks.add(event.callback).size)INVOKE_CALLBACK(event.callback,value,callbacks)}else INVOKE_CALLBACK(event.callback,value,callbacks)}),new Set});for(let consumer of consumers){let callbacks=UPSERT_INVOKERS_BY_CONSUMER_AND_CONTEXT(consumer,context);for(let callback of callbacks)INVOKE_CALLBACK(callback,value,callbacks)}},getContextValue=(consumer,context)=>{let returnValue;return addContextListener(consumer,context,(value)=>{returnValue=value}),returnValue};var CONSUMERS_BY_PROVIDER=new Map,INVOKERS_BY_CONTEXT_BY_CONSUMER=new WeakMap,INVOKE_CALLBACK=(callback,value,callbacks)=>{try{callback(value,()=>{callbacks.delete(callback)})}catch{}},UPSERT_INVOKERS_BY_CONSUMER_AND_CONTEXT=(consumer,context)=>UPSERT(UPSERT(INVOKERS_BY_CONTEXT_BY_CONSUMER,consumer,()=>new Map),context,()=>new Set),UPSERT=(map,key,initializer,value)=>map.get(key)??(map.set(key,value=initializer()),value);export{setContextValue,removeContextListener,getContextValue,createContext,addContextListener,ContextRequestEvent}