npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fusedio/widget-sdk

v0.3.1

Published

SDK for building custom json-ui components for the Fused workbench

Readme

@fusedio/widget-sdk

React hooks and types for building custom json-ui components that run inside the Fused workbench canvas.

If you want to build a 3rd-party component catalog that the Fused workbench can load — a custom chart, a custom input, a domain-specific widget — this SDK is the contract your components depend on.

Status: pre-1.0. The public hook surface is stabilising but minor breaking changes may still happen between 0.x releases. The bridge interface (for host implementers) is more volatile and may grow.

Installation

npm install @fusedio/widget-sdk
# or
bun add @fusedio/widget-sdk

React ≥18 is a peer dependency.

The shape of a component

Every component receives a single element prop. Read your props out of element.props, return JSX.

import { useFusedParam, type ComponentRenderProps } from "@fusedio/widget-sdk";

interface CounterProps {
  param: string;
  label?: string;
  step?: number;
}

export function Counter({ element }: ComponentRenderProps<CounterProps>) {
  const { param, label = "Count", step = 1 } = element.props;
  const { value, setValue } = useFusedParam({ param, defaultValue: 0 });

  return (
    <button onClick={() => setValue(value + step)}>
      {label}: {value}
    </button>
  );
}

When the user clicks, setValue broadcasts the new value to the canvas; any connected UDF re-runs with the updated parameter.

What the hooks let you do

| Hook | What it does | | ------------------------------ | ------------------------------------------------------------------- | | useFusedParam | Two-way bind a component to a canvas parameter (debounced). | | useCanvasParams | Read multiple canvas parameter values at once (edge-filtered). | | useParamSubstitution | Resolve $param and {{udf}} placeholders inside a template. | | useUdfOutputByName | Subscribe to a UDF's output, status, error. | | useUdfExecutor | Run a UDF on an event (udf?param=1); resolves $param at fire time. | | useUdfColumnValue / Values | Pull values out of {{udf.col}} / {{udf.col[idx]}} queries. | | useUdfDataFrameSample | Sample rows from a UDF's DataFrame output. | | useDuckDbSqlQuery | Run a DuckDB-WASM query against UDF parquet outputs in the browser. | | useUrlSigning / useMediaSrc | Sign s3://, gs://, fd:// URLs and resolve media sources. | | useUploadAccessCheck | Pre-flight an upload destination for write access. | | useAllowedSources | Which UDFs are allowed to broadcast to this node? | | useAllowedUdfNames | Set of UDF names this node may reference. | | useJsonUiEdgeAnimation | Animate the canvas edge pellet around custom async work. | | useJsonUiLog | Write entries to the runtime logs panel. | | useJsonUiUdfInfo | Current node identity (udfName, udfUniqueId, configHash). |

Every hook ships with @example blocks in its TypeScript declarations — hover any import in your editor for the full signature, defaults, and usage notes.

Param flow at a glance

   Component A                                 Component B
   useFusedParam("city")                       useFusedParam("city")
        │                                            ▲
        ▼                                            │
  setValue("NYC")                                    │
        │                                            │
        ▼                                            │
  Fused workbench                                    │
   ─ broadcasts on BroadcastChannel ─►  edge-filtered routing
                                              │
                                              ▼
                                       value = "NYC"
  • Values broadcast over a same-origin BroadcastChannel("parameter-updates").
  • The workbench filters by canvas edges: a component only receives values from upstream-connected nodes.
  • setValue debounces (300ms default). Use broadcastNow to flush immediately (e.g. onMouseUp of a slider). Use clearValue to reset and notify the canvas.

Running against the workbench

In the deployed Fused workbench your component is loaded as part of a catalog bundle: a single ESM file built with esbuild that the user adds to the workbench via Settings → Custom Catalogs. A minimal build looks like:

esbuild src/index.ts --bundle --format=esm --outfile=dist/catalog.esm.js \
  --external:react --external:react/jsx-runtime \
  --external:@fusedio/widget-sdk --external:zod

These four specifiers are marked external because the workbench injects a runtime import map that resolves them to its own already-loaded React, SDK, and Zod instances — guaranteeing one React instance, one SDK instance, one Zod instance across host + every loaded catalog. Without that, hook calls hit a different React instance ("invalid hook call"), and Zod schemas fail instanceof checks inside the workbench's z.toJSONSchema(...) pass.

A starter template (with a local sandbox, hot reload, and a GitHub Action that publishes the built bundle) will be linked here once it's published.

Architecture

This SDK is a thin shell:

  • FusedWidgetBridge is the interface the host implements (canvas params, UDF outputs, SQL execution, URL signing, …).
  • Hooks read the bridge from FusedWidgetBridgeContext and adapt it to React via useSyncExternalStore.
  • Pure utilities (utils/sql-placeholders.ts) parse SQL templates with no host dependencies.

The SDK itself does no I/O, no fetches, no auth, no storage. Every side effect goes through the bridge — which the host (the Fused workbench or your test harness) provides. This is why the same component code runs unchanged in the workbench, in a local sandbox, and in any future host.

Implementing a custom host (advanced)

Hosting json-ui components outside the Fused workbench:

import {
  FusedWidgetBridgeContext,
  type FusedWidgetBridge,
} from "@fusedio/widget-sdk";

const myBridge: FusedWidgetBridge = {
  params: { /* … */ },
  udfs: { /* … */ },
  // … everything else
};

<FusedWidgetBridgeContext.Provider value={myBridge}>
  {/* render json-ui components here */}
</FusedWidgetBridgeContext.Provider>

You'll need to implement every sub-bridge (params, udfs, routing, sql, template, uploads, edges, log, plus signUrl and node). The exhaustive interface is exported as FusedWidgetBridge — hover it in your editor for the full type.

License

Apache-2.0