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

@startinblox/glcdi

v1.0.4

Published

Startin'blox GLCDI Components

Readme

@startinblox/glcdi

GLCDI-specific Lit / Startin'blox web components, built on the upstream solid-boilerplate component scaffold (Lit + Startin'blox Core / Store / Router / Orbit, Vite, Storybook, Cypress, BiomeJS).

The package powers the catalogue UI shipped with each GLCDI participant deployment (participant-ui in glcdi). It is consumed via Hubl's npm[] config — see Use in participant-ui below.

What's in this package

| Component | Purpose | |---|---| | <sib-auth-apikey> + <sib-auth-provider-apikey> | API-key-only auth element. Drop-in compatible with <sib-auth-oidc> consumers — fires sib-auth:activated with { fetch, session }, exposes getFetch() / getUserWebId() / getSession() / isAuthenticated() / login() / logout(). Replaces OIDC redirect with an operator-pastes-an-X-Api-Key UX (GLCDI Tier 1). See management/IMPLEM_PLAN.md § Identity Tiering Strategy. | | <solid-glcdi> | Sample OrbitComponent showing how to wire a data-driven Lit element into the Orbit lifecycle. Boilerplate carry-over — useful as a copy-base for new GLCDI views. | | <sample-object> / <sample-objects> | Demo ComponentObjectHandler / ComponentObjectsHandler pattern for rendering individual objects and collections. |

Install

The package is published to latest on npm; the catalogue UI loads it via JSDelivr at runtime through Hubl's npm[] config.

<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/@startinblox/glcdi@latest/+esm"
  defer
></script>

For an end-to-end demo without Hubl:

<script type="module" src="https://cdn.jsdelivr.net/npm/@startinblox/core@latest/dist/store.js" defer></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@startinblox/glcdi@latest/+esm" defer></script>

<sib-auth-apikey
  data-participant-id="urn:glcdi:participant:caney-fork"
  data-participant-name="Caney Fork"
  auto-login
></sib-auth-apikey>

Use in participant-ui

Hubl's autoLogin partial supports an apikey branch (added for GLCDI Tier 1). Wire <sib-auth-apikey> from config.json like this:

"npm": [
  // ... existing entries ...
  {
    "package": "@startinblox/glcdi",
    "version": "latest",
    "path": "https://cdn.jsdelivr.net/npm/@startinblox/glcdi@latest/+esm"
  }
],
"components": [
  {
    "type": "autoLogin",
    "parameters": {
      "apikey": true,
      "participant-id": "${PARTICIPANT_ID}",
      "participant-name": "${APP_TITLE}",
      "storage-key-prefix": "glcdi_operator_api_key",
      "provider-label": "${APP_TITLE} connector",
      "management-url": "/management"
    },
    "route": false
  }
]

Hubl renders that as <sib-auth-apikey data-participant-id="…" auto-login="true">…</sib-auth-apikey>. The element auto-creates a <sib-auth-provider-apikey> child if none is supplied, so a single config entry is enough.

When IMPLEM_PLAN.md § 7.2 (Identity Tier 2 — user OIDC) lands, both apikey: true and oidc: true branches can coexist; downstream components consume whichever sib-auth:activated event they need.

Local development

npm install
npm run storybook       # primary dev environment, http://localhost:6006
npm run cy:open         # Cypress UI for component tests
npm run cy:run          # headless Cypress run
npm run build           # build the package
npm run locale:extract  # update localisation files
npm run locale:build    # build localisation bundles before publishing

The package itself ships without an index.html — Storybook is the primary in-package surface for visual iteration. To exercise the components inside a real Hubl-driven UI, point a local participant-ui build at the local component bundle (npm link) or at a published preview tag.

Tests

| Layer | Where | |---|---| | Component tests | cypress/component/*.cy.tscy.mount(html) per component | | Storybook variants | stories/*.stories.ts |

Tests for the auth elements live at cypress/component/sib-auth-apikey.cy.ts and stories at stories/sib-auth-apikey.stories.ts.

Forking notes (upstream sync)

scripts/init.js is the boilerplate's project-rename helper, kept here intentionally so a future GLCDI-derived component package can fork from solid-glcdi the same way solid-glcdi itself was forked from solid-boilerplate. Run it after cloning the package under a new name:

git clone https://git.startinblox.com/components/solid-glcdi.git your-new-component-name
cd your-new-component-name
npm install
npm run init     # walks you through the rename

To pull in upstream improvements from the boilerplate:

git remote add upstream https://git.startinblox.com/components/solid-boilerplate.git
git fetch upstream
git merge upstream/master

Resolve conflicts in package.json, README.md, and any renamed files (src/components/solid-glcdi.ts, cypress/component/solid-glcdi.cy.ts).

Core concepts (inherited from solid-boilerplate)

The technical surface — OrbitComponent, ObjectsHandler, ObjectHandler, store reactivity helpers (setupCacheInvalidation, setupOnResourceReady, setupOnSaveReset), cherryPickedProperties shape, available helpers under src/helpers/ — is unchanged from the upstream boilerplate. See the upstream README for that documentation; everything below carries over identically.

OrbitComponent quick reference

Attributes: defaultDataSrc (track original src), dataSrc (resource to display), nestedField (manual handling within Lit Task), uniq (duplicate in same DOM), route (router-aware gating), cherryPickedProperties (declared RDF / named props).

Methods: render, _afterAttach, _navigate(e), _getProxyValue(dataSrc), _responseAdaptator(res), gatekeeper.

Events: component-ready (after attach + init).

OrbitComponent inherits methods from ObjectsHandler.

cherryPickedProperties

cherryPickedProperties: PropertiesPicker[] = [
  { key: "name", value: "name" },
  { key: "project", value: "projectId", cast: (r) => r["@id"] },
  { key: "project", value: "project", expand: true },
  { key: "description", value: "description" },
];

Each entry: key (RDF / named source), value (component-side rename), cast (transform callback, e.g. formatDate), expand (recursive expansion with same cherryPickedProperties; watch out for circular deps — _responseAdaptator is usually a better fit for those).

Helpers

src/helpers/:

  • datas/dataBuilder (mock data), filterGenerator (filterObjectByX), sort
  • ui/formatDate (Intl-based), lipsum (mock copy)
  • utils/requestNavigation (Router wrapper), uniq (id generator)

Localisation

Configured via @lit/localize. Edit lit-localize.json (targetLocales), then:

npm run locale:extract   # regenerate XLIFF files in locales/ from `str` / `msg` calls
npm run locale:build     # build localisation bundle (run before deploy)

Runtime locale switch:

window.setLocale.map((setLocale) => setLocale("fr"));   // with Orbit
window.setLocale("fr");                                 // without Orbit

Orbit integration

Components are designed to work with Orbit out of the box.

  • import @src/initializer; at the top of any component file that runs in Orbit prevents race conditions on Orbit boot. Skip the import if the component will be used standalone.
  • gatekeeper in OrbitComponent.render() skips work when the current route doesn't match — significant performance lever in route-heavy apps.
  • Without Orbit some integrations degrade (route management, component deduplication, global localisation, conditional display).

Best practices

Standard MDN / webcomponents.org guidance applies. The boilerplate's gatekeeper + localisation are not optional polish — they're load-bearing when the component renders inside a real Hubl/Orbit app.

License

MIT