@dschz/solid-uplot
Version:
SolidJS wrapper for uPlot — ultra-fast, tiny time-series & charting library
127 lines (124 loc) • 4.26 kB
TypeScript
import { Store, SetStoreFunction } from 'solid-js/store';
/** Base constraint for plugin bus data structures */
type VoidStruct = Record<string, unknown>;
/**
* Internal type representing the plugin store structure
* @internal
*/
type PluginStore<T> = {
readonly data: Store<T>;
readonly setData: SetStoreFunction<T>;
};
/**
* Creates a reactive store shared across SolidUplot plugins.
*
* This store acts as a message bus, allowing plugins to publish and
* subscribe to typed messages based on agreed-upon keys (e.g., `tooltip`, `highlight`).
*
* @template T - The type of the plugin bus data structure
* @param initialData - Initial data for the plugin bus
* @returns A reactive store with data and setData functions
*
* @example
* ```tsx
* type MyBusData = {
* tooltip?: { x: number; y: number; visible: boolean };
* highlight?: { seriesIndex: number };
* };
*
* const bus = createPluginBus<MyBusData>();
* ```
*/
declare const createPluginBus: <T extends VoidStruct = VoidStruct>(initialData?: T) => PluginStore<T>;
/**
* Type representing a SolidUplot plugin bus instance
*
* @template T - The type of the plugin bus data structure
*/
type SolidUplotPluginBus<T extends VoidStruct = VoidStruct> = ReturnType<typeof createPluginBus<T>>;
/**
* Context object passed to plugin factory functions
*
* @template T - The type of the plugin bus data structure
*/
type UplotPluginFactoryContext<T extends VoidStruct = VoidStruct> = {
/** The plugin communication bus for sharing data between plugins */
readonly bus?: SolidUplotPluginBus<T>;
};
/**
* Factory function type for creating uPlot plugins with access to the SolidUplot plugin bus
*
* This allows plugins to communicate with each other and share state reactively through
* the SolidJS store system. Plugin factories receive a context object containing the
* plugin bus and return a standard uPlot plugin.
*
* When authoring plugins for public consumption, follow this pattern:
* 1. Define your plugin's message type
* 2. Define your plugin's message bus type
* 3. Export your plugin factory with proper type constraints
* 4. Include bus validation and warning messages
*
* @template T - The type of the plugin bus data structure for type-safe communication
*
* @param ctx - Context object containing the plugin bus and other shared resources
* @returns A standard uPlot plugin object with hooks
*
* @example
* ```tsx
* import type { UplotPluginFactory } from '@dschz/solid-uplot';
* import type { CursorPluginMessageBus } from '@dschz/solid-uplot/plugins';
*
* // 1. Define your plugin's message type
* export type MyPluginMessage = {
* value: number;
* timestamp: number;
* };
*
* // 2. Define your plugin's message bus type
* export type MyPluginMessageBus = {
* myPlugin?: MyPluginMessage;
* };
*
* // 3. Export your plugin factory with proper type constraints
* export const myPlugin = (
* options = {},
* ): UplotPluginFactory<CursorPluginMessageBus & MyPluginMessageBus> => {
* return ({ bus }) => {
* // 4. Include bus validation and warning
* if (!bus) {
* console.warn("[my-plugin]: A plugin bus is required");
* return { hooks: {} };
* }
*
* return {
* hooks: {
* ready: (u) => {
* // Initialize plugin state
* bus.setData("myPlugin", {
* value: 0,
* timestamp: Date.now(),
* });
* },
* setData: (u) => {
* // Update plugin state reactively
* bus.setData("myPlugin", "value", (prev) => prev + 1);
* },
* },
* };
* };
* };
*
* // Usage with proper typing
* const bus = createPluginBus<CursorPluginMessageBus & MyPluginMessageBus>();
*
* <SolidUplot
* data={data}
* pluginBus={bus}
* plugins={[cursor(), myPlugin()]}
* />
* ```
*
* @see {@link https://github.com/leeoniya/uPlot/tree/master/docs#plugins} uPlot Plugin Documentation
*/
type UplotPluginFactory<T extends VoidStruct = VoidStruct> = (ctx: UplotPluginFactoryContext<T>) => uPlot.Plugin;
export { type SolidUplotPluginBus as S, type UplotPluginFactory as U, type VoidStruct as V, type UplotPluginFactoryContext as a, createPluginBus as c };