@dschz/solid-uplot 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,10 +4,8 @@
4
4
 
5
5
  # @dschz/solid-uplot
6
6
 
7
- [![SolidJS](https://img.shields.io/badge/SolidJS-≥1.6.0-2c4f7c?logo=solid&logoColor=c8c9cb)](https://www.solidjs.com)
8
7
  [![uPlot](https://img.shields.io/badge/uPlot-%3E%3D1.6.32-orange)](https://github.com/leeoniya/uPlot)
9
8
  [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
10
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.8+-blue)](https://www.typescriptlang.org)
11
9
  [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@dschz/solid-uplot)](https://bundlephobia.com/package/@dschz/solid-uplot)
12
10
  [![npm](https://img.shields.io/npm/v/@dschz/solid-uplot)](https://www.npmjs.com/package/@dschz/solid-uplot)
13
11
 
@@ -42,7 +40,11 @@ Core components and plugin system:
42
40
 
43
41
  ```tsx
44
42
  import { SolidUplot, createPluginBus } from "@dschz/solid-uplot";
45
- import type { PluginFactory, SolidUplotPluginBus } from "@dschz/solid-uplot";
43
+ import type {
44
+ SolidUplotPluginBus,
45
+ UplotPluginFactory,
46
+ UplotPluginFactoryContext,
47
+ } from "@dschz/solid-uplot";
46
48
  ```
47
49
 
48
50
  ### `@dschz/solid-uplot/plugins`
@@ -376,7 +378,7 @@ const MyChart = () => {
376
378
  The plugin system is open to extension. When authoring plugins for public consumption, follow this pattern:
377
379
 
378
380
  ```tsx
379
- import type { PluginFactory } from "@dschz/solid-uplot";
381
+ import type { UplotPluginFactory } from "@dschz/solid-uplot";
380
382
  import type { CursorPluginMessageBus } from "@dschz/solid-uplot/plugins";
381
383
 
382
384
  // 1. Define your plugin's message type
@@ -393,7 +395,7 @@ export type MyPluginMessageBus = {
393
395
  // 3. Export your plugin factory
394
396
  export const myPlugin = (
395
397
  options = {},
396
- ): PluginFactory<CursorPluginMessageBus & MyPluginMessageBus> => {
398
+ ): UplotPluginFactory<CursorPluginMessageBus & MyPluginMessageBus> => {
397
399
  return ({ bus }) => {
398
400
  if (!bus) {
399
401
  console.warn("[my-plugin]: A plugin bus is required");
@@ -457,73 +459,67 @@ const MyDashboard = () => {
457
459
  ### SolidUplot Component
458
460
 
459
461
  ```tsx
460
- type SolidUplotProps<T extends VoidStruct = VoidStruct> = {
461
- // Chart data (required)
462
- data: uPlot.AlignedData;
462
+ // Main component props (extends all uPlot.Options except plugins, width, height)
463
+ type SolidUplotProps<T extends VoidStruct = VoidStruct> = SolidUplotOptions<T> & {
464
+ // Ref callback to access the chart container element
465
+ ref?: (el: HTMLDivElement) => void;
466
+
467
+ // Callback fired when the uPlot instance is created
468
+ onCreate?: (u: uPlot, meta: { seriesData: SeriesDatum[] }) => void;
469
+
470
+ // Whether to reset scales when chart data is updated (default: true)
471
+ resetScales?: boolean;
463
472
 
473
+ // CSS styles for the chart container (position is managed internally)
474
+ style?: Omit<JSX.CSSProperties, "position">;
475
+
476
+ // Where to place children components relative to the chart (default: "top")
477
+ childrenPlacement?: "top" | "bottom";
478
+
479
+ // Enable automatic resizing to fit container (default: false)
480
+ autoResize?: boolean;
481
+ };
482
+
483
+ // Configuration options extending uPlot.Options with SolidJS enhancements
484
+ type SolidUplotOptions<T extends VoidStruct = VoidStruct> = Omit<
485
+ uPlot.Options,
486
+ "plugins" | "width" | "height"
487
+ > & {
464
488
  // Chart dimensions
465
489
  width?: number; // default: 600
466
490
  height?: number; // default: 300
467
491
 
468
- // Responsive sizing
469
- autoResize?: boolean; // default: false
470
-
471
492
  // Plugin configuration
472
493
  plugins?: SolidUplotPlugin<T>[];
473
494
  pluginBus?: SolidUplotPluginBus<T>;
474
-
475
- // Chart options (all uPlot.Options except plugins, width, height)
476
- series?: uPlot.Series[];
477
- scales?: uPlot.Scales;
478
- axes?: uPlot.Axis[];
479
- // ... other uPlot options
480
-
481
- // Chart behavior
482
- resetScales?: boolean; // default: true
483
-
484
- // Callbacks
485
- onCreate?: (u: uPlot, meta: { seriesData: SeriesDatum[] }) => void;
486
-
487
- // Container styling
488
- style?: JSX.CSSProperties;
489
- class?: string;
490
- id?: string;
491
- ref?: (el: HTMLDivElement) => void;
492
-
493
- // Children placement
494
- childrenPlacement?: "top" | "bottom"; // default: "top"
495
495
  };
496
+
497
+ // Plugin type (can be standard uPlot plugin or factory function)
498
+ type SolidUplotPlugin<T extends VoidStruct = VoidStruct> = uPlot.Plugin | UplotPluginFactory<T>;
496
499
  ```
497
500
 
498
501
  ### Plugin Bus
499
502
 
500
503
  ```tsx
501
- type SolidUplotPluginBus<T extends VoidStruct = VoidStruct> = {
502
- data: T;
503
- setData: <K extends keyof T>(key: K, value: T[K]) => void;
504
- setData: <K extends keyof T, P extends keyof T[K]>(
505
- key: K,
506
- path: P,
507
- value: T[K][P]
508
- ) => void;
509
- };
504
+ // Plugin bus type (derived from createPluginBus return type)
505
+ type SolidUplotPluginBus<T extends VoidStruct = VoidStruct> = ReturnType<typeof createPluginBus<T>>;
510
506
 
511
507
  // Create a plugin bus
512
- const createPluginBus = <T extends VoidStruct = VoidStruct>(
513
- initialData?: Partial<T>
514
- ): SolidUplotPluginBus<T>;
508
+ const createPluginBus: <T extends VoidStruct = VoidStruct>(
509
+ initialData?: T,
510
+ ) => SolidUplotPluginBus<T>;
515
511
  ```
516
512
 
517
513
  ### Built-in Plugin Options
518
514
 
519
515
  ```tsx
520
516
  // Cursor Plugin
521
- const cursor = (): PluginFactory<CursorPluginMessageBus>;
517
+ const cursor = (): UplotPluginFactory<CursorPluginMessageBus>;
522
518
 
523
519
  // Focus Series Plugin
524
520
  const focusSeries = (options?: {
525
521
  pxThreshold?: number; // default: 15
526
- }): PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
522
+ }): UplotPluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
527
523
 
528
524
  // Tooltip Plugin
529
525
  const tooltip = (
@@ -535,7 +531,7 @@ const tooltip = (
535
531
  style?: JSX.CSSProperties;
536
532
  zIndex?: number; // default: 20
537
533
  }
538
- ): PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
534
+ ): UplotPluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
539
535
 
540
536
  // Legend Plugin
541
537
  const legend = (
@@ -548,7 +544,7 @@ const legend = (
548
544
  style?: JSX.CSSProperties;
549
545
  zIndex?: number; // default: 10
550
546
  }
551
- ): PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
547
+ ): UplotPluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
552
548
  ```
553
549
 
554
550
  ## 📚 Examples
@@ -0,0 +1,126 @@
1
+ import { Store, SetStoreFunction } from 'solid-js/store';
2
+
3
+ /** Base constraint for plugin bus data structures */
4
+ type VoidStruct = Record<string, unknown>;
5
+ /**
6
+ * Internal type representing the plugin store structure
7
+ * @internal
8
+ */
9
+ type PluginStore<T> = {
10
+ readonly data: Store<T>;
11
+ readonly setData: SetStoreFunction<T>;
12
+ };
13
+ /**
14
+ * Creates a reactive store shared across SolidUplot plugins.
15
+ *
16
+ * This store acts as a message bus, allowing plugins to publish and
17
+ * subscribe to typed messages based on agreed-upon keys (e.g., `tooltip`, `highlight`).
18
+ *
19
+ * @template T - The type of the plugin bus data structure
20
+ * @param initialData - Initial data for the plugin bus
21
+ * @returns A reactive store with data and setData functions
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * type MyBusData = {
26
+ * tooltip?: { x: number; y: number; visible: boolean };
27
+ * highlight?: { seriesIndex: number };
28
+ * };
29
+ *
30
+ * const bus = createPluginBus<MyBusData>();
31
+ * ```
32
+ */
33
+ declare const createPluginBus: <T extends VoidStruct = VoidStruct>(initialData?: T) => PluginStore<T>;
34
+ /**
35
+ * Type representing a SolidUplot plugin bus instance
36
+ *
37
+ * @template T - The type of the plugin bus data structure
38
+ */
39
+ type SolidUplotPluginBus<T extends VoidStruct = VoidStruct> = ReturnType<typeof createPluginBus<T>>;
40
+ /**
41
+ * Context object passed to plugin factory functions
42
+ *
43
+ * @template T - The type of the plugin bus data structure
44
+ */
45
+ type UplotPluginFactoryContext<T extends VoidStruct = VoidStruct> = {
46
+ /** The plugin communication bus for sharing data between plugins */
47
+ readonly bus?: SolidUplotPluginBus<T>;
48
+ };
49
+ /**
50
+ * Factory function type for creating uPlot plugins with access to the SolidUplot plugin bus
51
+ *
52
+ * This allows plugins to communicate with each other and share state reactively through
53
+ * the SolidJS store system. Plugin factories receive a context object containing the
54
+ * plugin bus and return a standard uPlot plugin.
55
+ *
56
+ * When authoring plugins for public consumption, follow this pattern:
57
+ * 1. Define your plugin's message type
58
+ * 2. Define your plugin's message bus type
59
+ * 3. Export your plugin factory with proper type constraints
60
+ * 4. Include bus validation and warning messages
61
+ *
62
+ * @template T - The type of the plugin bus data structure for type-safe communication
63
+ *
64
+ * @param ctx - Context object containing the plugin bus and other shared resources
65
+ * @returns A standard uPlot plugin object with hooks
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * import type { UplotPluginFactory } from '@dschz/solid-uplot';
70
+ * import type { CursorPluginMessageBus } from '@dschz/solid-uplot/plugins';
71
+ *
72
+ * // 1. Define your plugin's message type
73
+ * export type MyPluginMessage = {
74
+ * value: number;
75
+ * timestamp: number;
76
+ * };
77
+ *
78
+ * // 2. Define your plugin's message bus type
79
+ * export type MyPluginMessageBus = {
80
+ * myPlugin?: MyPluginMessage;
81
+ * };
82
+ *
83
+ * // 3. Export your plugin factory with proper type constraints
84
+ * export const myPlugin = (
85
+ * options = {},
86
+ * ): UplotPluginFactory<CursorPluginMessageBus & MyPluginMessageBus> => {
87
+ * return ({ bus }) => {
88
+ * // 4. Include bus validation and warning
89
+ * if (!bus) {
90
+ * console.warn("[my-plugin]: A plugin bus is required");
91
+ * return { hooks: {} };
92
+ * }
93
+ *
94
+ * return {
95
+ * hooks: {
96
+ * ready: (u) => {
97
+ * // Initialize plugin state
98
+ * bus.setData("myPlugin", {
99
+ * value: 0,
100
+ * timestamp: Date.now(),
101
+ * });
102
+ * },
103
+ * setData: (u) => {
104
+ * // Update plugin state reactively
105
+ * bus.setData("myPlugin", "value", (prev) => prev + 1);
106
+ * },
107
+ * },
108
+ * };
109
+ * };
110
+ * };
111
+ *
112
+ * // Usage with proper typing
113
+ * const bus = createPluginBus<CursorPluginMessageBus & MyPluginMessageBus>();
114
+ *
115
+ * <SolidUplot
116
+ * data={data}
117
+ * pluginBus={bus}
118
+ * plugins={[cursor(), myPlugin()]}
119
+ * />
120
+ * ```
121
+ *
122
+ * @see {@link https://github.com/leeoniya/uPlot/tree/master/docs#plugins} uPlot Plugin Documentation
123
+ */
124
+ type UplotPluginFactory<T extends VoidStruct = VoidStruct> = (ctx: UplotPluginFactoryContext<T>) => uPlot.Plugin;
125
+
126
+ export { type SolidUplotPluginBus as S, type UplotPluginFactory as U, type VoidStruct as V, type UplotPluginFactoryContext as a, createPluginBus as c };
@@ -1,5 +1,5 @@
1
- import { V as VoidStruct, S as SolidUplotPluginBus, P as PluginFactory } from '../createPluginBus-B_Gp5BCB.js';
2
- export { c as createPluginBus } from '../createPluginBus-B_Gp5BCB.js';
1
+ import { V as VoidStruct, S as SolidUplotPluginBus, U as UplotPluginFactory } from '../createPluginBus-DdrjQANs.js';
2
+ export { a as UplotPluginFactoryContext, c as createPluginBus } from '../createPluginBus-DdrjQANs.js';
3
3
  import { ParentProps, JSX } from 'solid-js';
4
4
  import uPlot from 'uplot';
5
5
  import { S as SeriesDatum } from '../getSeriesData-D1zBqQ9Y.js';
@@ -13,7 +13,7 @@ type ChildrenPlacement = "top" | "bottom";
13
13
  *
14
14
  * @template T - The type of the plugin bus data structure
15
15
  */
16
- type SolidUplotPlugin<T extends VoidStruct = VoidStruct> = uPlot.Plugin | PluginFactory<T>;
16
+ type SolidUplotPlugin<T extends VoidStruct = VoidStruct> = uPlot.Plugin | UplotPluginFactory<T>;
17
17
  /**
18
18
  * Configuration options for the SolidUplot component, extending uPlot.Options
19
19
  * with SolidJS-specific enhancements
@@ -102,4 +102,4 @@ type SolidUplotProps<T extends VoidStruct = VoidStruct> = SolidUplotOptions<T> &
102
102
  */
103
103
  declare const SolidUplot: <T extends VoidStruct = VoidStruct>(props: ParentProps<SolidUplotProps<T>>) => JSX.Element;
104
104
 
105
- export { SolidUplot };
105
+ export { SolidUplot, SolidUplotPluginBus, UplotPluginFactory };
@@ -1,4 +1,4 @@
1
- import { P as PluginFactory, S as SolidUplotPluginBus } from '../createPluginBus-B_Gp5BCB.js';
1
+ import { U as UplotPluginFactory, S as SolidUplotPluginBus } from '../createPluginBus-DdrjQANs.js';
2
2
  import { C as CursorData } from '../getCursorData-2qxURGuZ.js';
3
3
  import { Component, JSX } from 'solid-js';
4
4
  import uPlot from 'uplot';
@@ -75,7 +75,7 @@ type CursorPluginMessageBus = {
75
75
  * ];
76
76
  * ```
77
77
  */
78
- declare const cursor: () => PluginFactory<CursorPluginMessageBus>;
78
+ declare const cursor: () => UplotPluginFactory<CursorPluginMessageBus>;
79
79
 
80
80
  /**
81
81
  * Target a series by its label.
@@ -220,7 +220,7 @@ type FocusSeriesPluginOptions = {
220
220
  * @param options - Configuration options for focus behavior
221
221
  * @returns A plugin factory function that creates the focus series plugin instance
222
222
  */
223
- declare const focusSeries: (options?: FocusSeriesPluginOptions) => PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
223
+ declare const focusSeries: (options?: FocusSeriesPluginOptions) => UplotPluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
224
224
 
225
225
  /**
226
226
  * Simple legend placement options - only top corners to avoid axis conflicts
@@ -291,7 +291,7 @@ type LegendPluginOptions = LegendRootProps & LegendConfigOptions;
291
291
  * @param options - Configuration options for legend behavior and styling
292
292
  * @returns A plugin factory function that creates the legend plugin instance
293
293
  */
294
- declare const legend: (Component: Component<LegendProps>, options?: LegendPluginOptions) => PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
294
+ declare const legend: (Component: Component<LegendProps>, options?: LegendPluginOptions) => UplotPluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
295
295
 
296
296
  /**
297
297
  * Defines the preferred placement of the tooltip relative to the cursor position.
@@ -445,6 +445,6 @@ type TooltipPluginOptions = TooltipRootProps & TooltipConfigOptions;
445
445
  * @param options - Configuration options for tooltip behavior and styling
446
446
  * @returns A plugin factory function that creates the tooltip plugin instance
447
447
  */
448
- declare const tooltip: (Component: Component<TooltipProps>, options?: TooltipPluginOptions) => PluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
448
+ declare const tooltip: (Component: Component<TooltipProps>, options?: TooltipPluginOptions) => UplotPluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus>;
449
449
 
450
450
  export { type CursorPluginMessage, type CursorPluginMessageBus, type FocusSeriesPluginMessage, type FocusSeriesPluginMessageBus, type LegendProps, type TooltipProps, cursor, focusSeries, legend, tooltip };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dschz/solid-uplot",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "SolidJS wrapper for uPlot — ultra-fast, tiny time-series & charting library",
5
5
  "type": "module",
6
6
  "author": "Daniel Sanchez <dsanc89@pm.me>",
@@ -1,21 +0,0 @@
1
- import { Store, SetStoreFunction } from 'solid-js/store';
2
-
3
- type VoidStruct = Record<string, unknown>;
4
- type PluginStore<T> = {
5
- readonly data: Store<T>;
6
- readonly setData: SetStoreFunction<T>;
7
- };
8
- /**
9
- * Represents a reactive store shared across SolidUplot plugins.
10
- *
11
- * This store acts as a message bus, allowing plugins to publish and
12
- * subscribe to typed messages based on agreed-upon keys (e.g., `tooltip`, `highlight`).
13
- */
14
- declare const createPluginBus: <T extends VoidStruct = VoidStruct>(initialData?: T) => PluginStore<T>;
15
- type SolidUplotPluginBus<T extends VoidStruct = VoidStruct> = ReturnType<typeof createPluginBus<T>>;
16
- type PluginFactoryContext<T extends VoidStruct = VoidStruct> = {
17
- readonly bus?: SolidUplotPluginBus<T>;
18
- };
19
- type PluginFactory<T extends VoidStruct = VoidStruct> = (ctx: PluginFactoryContext<T>) => uPlot.Plugin;
20
-
21
- export { type PluginFactory as P, type SolidUplotPluginBus as S, type VoidStruct as V, createPluginBus as c };