Detalhes do pacote

context-protocol

jsxtools48MIT-00.0.4

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

api, bubble, bubbles, callback

readme (leia-me)

Context Protocol

NPM Version Build Status Coverage

Context Protocol is a fully-typed implementation of the Context Protocol proposal — a standardized, platform-agnostic way for components to communicate shared state or services from any location in the DOM.

Features

  • 🚀 Fully Typed: Full TypeScript support with comprehensive type safety and autocompletion.
  • 🧠 Fully Tested: 100% test coverage ensuring reliability.
  • 📦 Tree-shakeable: Import only what you need to keep your bundle size minimal.
  • 🎯 Framework Agnostic: Works with any web framework or vanilla JavaScript.
  • 🔄 Reactive: Additional subscription helpers for real-time context updates.
  • 🛠️ Mixable: Easy integration with custom elements via mixin helpers.

Installation

npm install context-protocol

Basic Usage

At its core, Context Protocol provides the typing and event-driven behavior as defined in the Context Protocol proposal.

import { ContextRequestEvent, createContext } from "context-protocol"

// create a context for theme management
const themeContext = createContext<"light" | "dark">("theme")

document.dispatchEvent(
  new ContextRequestEvent(themeContext, (value, unsubscribe) => {
    // do stuff with the context value
  }, true)
)

Use this low-level API with any framework or library that follows the proposal — or build your own tools on top of it.

Prefer a more ergonomic, batteries-included approach? This package also offers a minimal, tree-shakeable Subscription API built on top of Context Protocol, making it easy to provide and consume context out of the box.


Subscription API

Need live context updates? Use these helpers to get and set real-time context values.

import {
  createContext,
  setContextValue,
  getContextValue
} from "context-protocol/subscriptions"

// create a context for theme management
const themeContext = createContext<"light" | "dark">("theme")

// set the context value
setContextValue(document, themeContext, "dark")

// get the context value
const theme = getContextValue(document, themeContext)

console.log(theme) // "dark"

Want to respond to changes? Use these listeners to react as context updates happen.

import {
  createContext,
  setContextValue,
  addContextListener,
} from "context-protocol/subscriptions"

// create a context for user preferences
const userContext = createContext<{ name: string; age: number }>("user")

// set up a listener for user changes
addContextListener(document.body, userContext, (user, unsubscribe) => {
  console.log(`User updated: ${user.name} (${user.age})`)

  // unsubscribe when needed
  if (user.age > 950) unsubscribe()
}, true)

// update user data
setContextValue(document, userContext, { name: "Noah", age: 600 })

Jump to:


Core Concepts

Context Creation

// create a context with a specific value type
const themeContext = createContext<"light" | "dark">("theme")

// the value type can be anything
const userContext = createContext<{ name: string }>("user")

Providers and Consumers

You can set a value on any target, then retreive that value at any time from the target or any of its descendants.

setContextValue(document, context, value)

getContextValue(document.body, context) // returns value

Subscriptions

You can subscribe to context changes on any target, and remove the listener when it’s no longer needed.

const callback = (value, unsubscribe) => {
  // handle value changes
}

// listen now
addContextListener(element, context, callback, true)

// stop listening later
removeContextListener(element, context, callback)

Skip ahead to learn how the addContextListener works.

Advanced Usage: Using Mixins

import { ContextConsumerMixin, ContextProviderMixin, createContext } from "context-protocol/mixins"

type Theme = "light" | "dark"
const themeContext = createContext<Theme>("light")

// create a custom element that provides context
class ThemeProvider extends ContextProviderMixin(HTMLElement) {
  setTheme(theme: Theme) {
    this.setContextValue(themeContext, theme)
  }
}

// create a custom element that consumes context
class ThemeAwareElement extends ContextConsumerMixin(HTMLElement) {
  connectedCallback() {
    this.addContextListener(themeContext, (theme) => {
      this.style.backgroundColor = theme === "dark" ? "#333" : "#fff"
    })
  }
}

API Reference

createContext

Creates a new context identifier, scoped by a unique key and associated with a value type. This key is used to share and consume values through the Context Protocol.

createContext<ValueType>(key: unknown): Context<unknown, ValueType>

Type Parameters:

  • ValueType (unknown)
    The type of the value associated with the context, ensuring type safety to providers and consumers.

Parameters:

  • key (unknown)
    A key used to identify the context — typically a string, symbol, or object.

Returns:

  • context (Context<typeof key, ValueType>)
    A branded context object used for matching providers and consumers.

getContextValue

Retrieves the current value of a given context from a consumer node. This is a one-time lookup and does not subscribe to future updates.

getContextValue<T>(
  consumer: EventTarget,
  context: T,
): void

Type Parameters:

  • T (unknown)
    The context key or the branded context type returned by createContext().

Parameters:

  • consumer (EventTarget)
    The element or node requesting the context. The protocol will walk up the tree to find a matching provider.
  • context (T as Context)
    The context key or the branded context type returned by createContext().

Returns:

  • value (ContextType<T> | undefined)
    The resolved value from the nearest matching provider, or undefined if no value is found.

setContextValue

Delivers a value to a context, making it available to any matching consumers. If the consumer has subscribed to updates, its callback will be invoked immediately and again on future updates.

setContextValue<T>(
  provider: EventTarget,
  context: T,
  value: ContextType<T>
): void

Type Parameters:

  • T (unknown)
    The context key or the branded context type returned by createContext().

Parameters:

  • provider (EventTarget)
    The element or node acting as the context provider. Listeners will be attached here to respond to context requests.
  • context (T as Context)
    The context key or the branded context type returned by createContext().


Subscription Methods

addContextListener

Registers a callback to receive context values delivered to a specific target.

addContextListener<T>(
  consumer: EventTarget,
  context: ExtractContext<T>,
  callback: ContextCallback<ContextType<T>>,
  subscribe?: boolean,
): void

Type Parameters:

  • T (unknown)
    The context key or the branded context type returned by createContext().

Parameters:

  • consumer (EventTarget)
    The element or node that should receive the context. This is typically a DOM node that wants to consume a value.
  • context (T as Context)
    The context key or the branded context type returned by createContext().
  • callback ((value: T, unsubscribe?: () => void) => void)
    A function invoked with the resolved context value. If subscribe is true, the callback may be re-invoked when the context value changes. The callback receives an unsubscribe function if a subscription was made.
  • subscribe (boolean, optional)
    If true, the callback will be subscribed to future updates to this context. Defaults to false.

removeContextListener

Unregisters a previously registered context listener.

removeContextListener<T>(
  consumer: EventTarget,
  context: T,
  callback: ContextCallback<ContextType<T>>,
): void

Type Parameters:

  • T (unknown)
    The context key or the branded context type returned by createContext().

Parameters:

  • consumer (EventTarget)
    The element or node from which the listener should be removed.
  • context (T as Context)
    The context key or branded context type originally used.
  • callback ((value: T, unsubscribe?: () => void) => void)
    The callback function to remove. This must match the exact reference passed to addContextListener.


Subscription Mixins

ContextConsumerMixin

A mixin that equips any EventTarget class (like Custom Elements) with methods to consume context values.

ContextConsumerMixin<T extends EventTargetConstructor>(Target: T): T & ContextConsumerMixin.Constructor

Type Parameters:

  • T (EventTargetConstructor)
    A constructor function that returns an EventTarget instance. Commonly used with HTMLElement.

Returns:

  • ConsumerTarget (T & ContextConsumerMixin.Constructor)
    A class extended with consumer methods for context.

Adds the following methods:

  • addContextListener(context, callback, subscribe?)
    Subscribes to a context value. Optionally listens for future updates.
  • removeContextListener(context, callback)
    Unsubscribes a previously registered callback.

ContextProviderMixin

A mixin that equips any EventTarget class (like Custom Elements) with a method to provide context values to matching consumers.

ContextProviderMixin<T extends EventTargetConstructor>(Target: T): T & ContextProviderMixin.Constructor

Type Parameters:

  • T (EventTargetConstructor)
    A constructor function that returns an EventTarget instance. Commonly used with HTMLElement.

Returns:

  • ProviderTarget (T & ContextProviderMixin.Constructor)
    A class extended with provider methods for context.

Adds the following methods:

  • setContextValue(context, value)
    Provides a value to the given context, delivering it to all matching consumers.

Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m "Add amazing feature")
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT No Attribution License.