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

@pelicanplatform/hooks

v1.6.4

Published

Pelican React Hooks

Downloads

721

Readme

@pelicanplatform/hooks

React state bindings for the Pelican Platform web client. This package wraps the core, framework-agnostic @pelicanplatform/web-client in a React context so a whole component tree can share one configured client — with federation discovery, namespace resolution, token storage, the OAuth login flow, object-list caching, and live download progress all handled for you.

It has no UI of its own. If you want ready-made components, use @pelicanplatform/components (which builds on this package). If you want to build your own UI, use these hooks directly.

Installation

npm i @pelicanplatform/hooks

@pelicanplatform/web-client comes along as a dependency. React 17, 18, or 19 is a peer dependency and must be provided by your app.

What's exported

| Export | Type | Description | | --- | --- | --- | | PelicanClientProvider | component | Context provider that holds and manages all client state. Wrap your tree with it. | | PelicanClientProviderProps | type | Props for the provider. | | usePelicanClient | hook | Read the client state and actions from any descendant. Throws if used outside a provider. | | PelicanClientContext | context | The raw React context (rarely needed — prefer usePelicanClient). | | PelicanClientContextValue | type | The shape of everything the hook returns. | | DownloadProgress | type | Progress record for a single download. |

Quick start

Wrap your app (or the relevant subtree) in the provider, then read from it with the hook.

"use client";

import { PelicanClientProvider, usePelicanClient } from "@pelicanplatform/hooks";

function App() {
  return (
    <PelicanClientProvider
      initialObjectUrl="pelican://osg-htc.org/ncar"
      enableAuth={true}
    >
      <Browser />
    </PelicanClientProvider>
  );
}

function Browser() {
  const { objectUrl, getObjectList, handleDownload, loading } = usePelicanClient();
  // ...drive your own UI from the context
}

PelicanClientProvider props

| Prop | Default | Description | | --- | --- | --- | | initialObjectUrl | "" | The pelican://<federation>/<path> URL to load on mount. | | enableAuth | true | Enables the login flow and authenticated actions (upload, collections). Set to false for read-only, public access. | | children | — | Your component tree. |

What the provider does for you

State is derived from the current objectUrl. When it changes, the provider:

  • Discovers the federation for the URL's hostname and resolves the namespace for its path (deduplicating concurrent fetches).
  • Persists federations, namespace→prefix mappings, and tokens in sessionStorage (keys prefixed pelican-wc-), and prunes expired tokens.
  • Runs the OAuth authorization-code flow (with PKCE) on login and exchanges the returned code for a token.
  • Caches object lists with a 5-minute TTL, and exposes cache invalidation.
  • Subscribes to the download service worker and tracks live progress per download.

Because all of this lives in the provider, the components reading from it stay stateless.

usePelicanClient()

Returns the PelicanClientContextValue. Must be called inside a PelicanClientProvider — otherwise it throws:

usePelicanClient must be used within a PelicanClientProvider.

Context value reference

State

| Field | Type | Description | | --- | --- | --- | | enableAuth | boolean | The enableAuth prop, passed through. | | loading | boolean | True while metadata or an auth exchange is in flight. | | error | string \| null | Last error message (e.g. for a toast). | | authorizationRequired | boolean | The current URL needs login to be listed. | | authorized | boolean | A valid token granting one or more collections is present. | | objectUrl | string | The currently viewed pelican:// URL. | | federationHostname | string \| null | Hostname parsed from objectUrl. | | objectPath | string \| null | Object path parsed from objectUrl. | | federation | Federation \| null | Resolved federation metadata. | | namespace | Namespace \| null | Resolved namespace metadata. | | collections | Collection[] | Collections granted by the current token. | | downloadsInProgress | Record<string, DownloadProgress> | Live download progress, keyed by id. |

Actions

| Function | Description | | --- | --- | | setObjectUrl(url) | Navigate to a new pelican:// URL (a useState setter — accepts a value or updater). | | getObjectList(url?, forceRefresh?) | List objects at url (defaults to objectUrl); TTL-cached unless forceRefresh. Returns ObjectList[]. | | invalidateObjectListCache(url?) | Drop cached listings for url (and its parents), or all if omitted. | | handleDownload(url) | Stream a download of the object at url through the service worker. | | handleUpload(file, url?) | Upload a File to url (defaults to objectUrl); invalidates the relevant list cache. | | handleLogin() | Start the OAuth authorization-code flow for the current namespace. | | ensureMetadata(url, urlType) | Low-level: ensure the federation/namespace for url are fetched and cached. Returns { federation, namespace }. | | setError(message) | Set or clear (null) the error message. |

DownloadProgress

interface DownloadProgress {
  id: string;
  objectUrl: string;
  bytesDownloaded: number;
  totalByteSize: number;
  status: "pending" | "in-progress" | "completed" | "failed" | "cancelled";
}

Example: a minimal browser

"use client";

import { usePelicanClient } from "@pelicanplatform/hooks";
import { useEffect, useState } from "react";
import type { ObjectList } from "@pelicanplatform/web-client";

export function Browser() {
  const { objectUrl, setObjectUrl, getObjectList, handleDownload, handleLogin, authorized, loading } =
    usePelicanClient();

  const [objects, setObjects] = useState<ObjectList[]>([]);
  useEffect(() => {
    getObjectList(objectUrl).then(setObjects);
  }, [objectUrl, getObjectList]);

  if (loading) return <p>Loading…</p>;

  return (
    <>
      {!authorized && <button onClick={handleLogin}>Login</button>}
      <ul>
        {objects.map((o) => (
          <li key={o.href}>
            {o.iscollection ? (
              <button onClick={() => setObjectUrl(`pelican://osg-htc.org${o.href}`)}>{o.href}/</button>
            ) : (
              <button onClick={() => handleDownload(`pelican://osg-htc.org${o.href}`)}>{o.href}</button>
            )}
          </li>
        ))}
      </ul>
    </>
  );
}

Notes

  • The provider and hook are marked "use client". In the Next.js App Router, place PelicanClientProvider in a client boundary (commonly the root layout.tsx) and call usePelicanClient only from client components.
  • For live download progress to populate downloadsInProgress, register the download service worker shipped in @pelicanplatform/web-client (see that package's docs and the components README).
  • A full working example is in website/ at the repo root.

License

Apache-2.0.