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 🙏

© 2025 – Pkg Stats / Ryan Hefner

decent-portal

v2.4.7

Published

Decent Portal Library

Readme

decent-portal

This library contains functionality that can be added to a web app that the developer intends to deploy to the Decent Portal.

More specifically it includes:

  • The Decent Bar, a React component that displays at the top of apps hosted on the Decent Portal.

  • Predicting success/failure for loading a specific model based on system/model info and past history.

  • Predicting input/output characters per second for model based on past history.

  • Local logging to persistent storage (never sent to server) and copy-to-clipboard functionality.

  • Toast UI to show quick messages to user for errors and information.

  • Settings dialog with some built-in categories of settings (LLM, logging) and developer-definable app settings.

  • Scripts supporting deployment of the app to staging and production targets on the Decent Portal via Github workflows.

decent-portal is a dependency in project code generated by the create-decent-app tool (CDA). CDA vendors (in-lines) most source code so that developers can directly edit it. But anticipating a need for updates around Decent Portal-related functionality, I created this separate library to make it easy for devs to upgrade.

decent-portal allows for a single web app build that can simultaneously deploy to non-Decent-Portal hosting as well as the Decent Portal. The aim is to allow you to have a single build rather than requiring multiple builds. So, for example, the Decent Bar can be configured to not render at run-time based on the domain it is hosted from.

Using the DecentBar

If you're using the DecentBar, you probably intend for your web app to appear on the Decent Portal. And for that purpose, we ask that the DecentBar appears at the top of the page for your app. The idea is to have some consistency in app appearance and navigation. The elements of the Decent Bar:

  • A home button, which will just show the Decent "D" logo. Clicking on it will take the user to the home page of the portal.
  • The name of your app.
  • Link buttons - this is a conventional place to allow the user to navigate to other pages, maybe on other websites.
  • Contributors - put your name and other people's names that contributed to the project. You can omit this if you like. But consider that including your name is not just bragging -- it's reminding your users that a real person worked to make the software, and it's a gesture towards accountability.

Example:

<DecentBar 
  appName="Bleetbox" 
  links={[{description:"Support", url:"https://github.com/joedev/bleetbox/issues"}]} 
  contributorText="Joseph Blowsephius, Amy Hacksaw"
/>

DecentBar Component Properties

  • appName - This is the display name of your app.
  • contributorText (optional) - List names of people who contributed to the app here.
  • enabledDomains (optional) - List domain names that you want the DecentBar to render on. By default, this will include "decentapps.net", "localhost", and "127.0.0.1". The conditional rendering is useful for deploying the same web app to multiple hosting locations.
  • homeUrl (optional) - Where the user will navigate when they click on the home link. By default, this will be the base URL of wherever the web app is served, e.g., an app served from "https://decentapps.net/bleetbox" will have a default home URL of "https://decentapps.net".
  • links (optional) - An array of links, each of type Link, which is {description:string, url:string}. Description is what displays on the button. We recommend always including a "Support" link.
  • onClickLink (optional) - The callback function you can optionally implement to customize behavior of clicking links. See "Implementing onClickLink()" section below.
  • classNameOverrides (optional) - CSS overrides for any of the elements rendered by the bar. See "Overriding CSS" section below.

Implementing onClickLink()

If you just want to navigate to the URL provided in the link, you don't need to specify onClickLink or implement a handler. But you can use the handler to do things like:

  • Override the default behavior for opening URLs in a separate tab or window.
  • Check for unsaved user data before navigating away.
  • Open modal dialogs, popup menus, or other in-app UI rather than navigating to a new URL.

The "url" attribute of the link need not be an actual URL. It can just be a code that is interpreted by your handler. So for example:

import { DecentBar, Link, defaultOnClickLink } from 'decent-portal';

function _onClickLink(link:Link) {
  if (link.url === 'ABOUT') {
    window.prompt("I'm a very private person. But I'll share with you that I have assassinated seventy-three squirrels. It wasn't personal.");
    return;
  }
  defaultOnClickLink(link);
}

function HomeScreen() {
  const links:Link[] = [
    {support:"", url:"https://YourWebSite.com/support"},
    {description:"About Me", url:"ABOUT"}
  ];
  return (<div>
    <DecentBar appName="Squirrel Death" link={links} onClickLink={_onClickLink}/>
    <p>My stupid screen.</p>
  </div>);
}

When implementing your own onClickLink() handler, you should handle any links that need to do something besides the default behavior, and then let the rest be handled with a call to defaultOnClickLink(). In this way, you'll have consistent behavior with other apps on the Decent Portal. For example, there is logic in defaultOnClickLink() to navigate to a new tab for stay in same tab based on if the link is matching the current domain.

Whatever you do with your links and navigation, always be clear about sending the user away from the Decent Portal. Using the "Links" area of the DecentBar and opening the cross-domain link in a new tab (handled by defaultOnClickLink() automatically) should suffice for this.

Overriding CSS

The classNameOverrides property will let you specify a CSS class that will be applied in addition to the default CSS class. You can do things like adjust font sizes, margins, padding, and colors.

For hosting on Decent Portal, we want the DecentBar to look consistent across different apps, but a few tweaks to make the bar fit in with your app better are fine. Don't obstruct or obscure the navigational functionality.

An example of how to override the CSS can be found here.

DecentBar Behavior on Other Hosts

By default, if you deploy your app with DecentBar on a website that isn't the Decent Portal, it won't be shown. The bar will execute minimal code to not render into the DOM. Why have this conditional hiding behavior?

  • It allows you to build one web app and deploy it to multiple places. This lets you avoid setting up separate/conditional builds.
  • It avoids confusing users into thinking they are on the Decent Portal when they're somewhere else that might not have the same privacy guarantees.

You can easily override the hiding behavior with the "enabledDomains" property to include a non-Decent-Portal domain. But I suspect at that point, you might be better served by making your own bar so you can customize it for the experience you want on the non-Decent-Portal domain. You're welcome to reuse the DecentBar.tsx source as a starting point (vendoring!) if that suits you.

The home icon is loaded from whatever favorite icon (favicon.ico or header-linked file) is used by your web app, which for a Decent Portal-hosted app will just be the "D" icon.

Additional APIs

I'm planning to create a full reference documentation of available decent-portal APIs that publishes to a website. But until we get that, I recommend looking at ./src/index.ts to view the exports. And if you check the specific modules containing these exports, you'll probably find JSDoc comments there.

Licensing

This repository is licensed under the MIT open source license.

But if you see a LICENSE file in a sub-directory of the repository, that license will apply to all files found in that directory.

Contributing

The project isn't open to contributions at this point. But that could change. Contact me if you'd like to collaborate.

Contacting

You can reach me on LinkedIn. I'll accept connections if you will just mention some shared interest in your connection request.

https://www.linkedin.com/in/erikhermansen/