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

lor-cui-kit

v0.1.1

Published

Runtime utilities for lazy CUI card activation, layout stabilization, persistent previous-data hydration, and stale-while-revalidate behavior in React applications.

Readme

lor-cui-kit

English | 简体中文

Runtime kit for lazy CUI card activation, layout-stable height reservation, persistent previous-data hydration, and stale-while-revalidate in React chat / agent history views.

license node TypeScript ESM React SWR npm

Why you need it

Agent and IM history often mix plain text with rich CUI cards (orders, tickets, tools). A naive list mounts every card and fetches immediately. Fifty messages with ten cards means ten network calls on first paint, layout jumps when heights resolve, and wasted work for cards far below the viewport.

lor-cui-kit keeps the list cheap: shells reserve height, children mount only near the viewport, and a previous payload can hydrate from storage while a background refresh runs.

Core capabilities

  • Lazy activationCuiCardShell observes the viewport (preloadMargin default 600px 0px) and mounts children only when intersecting. Pass lazy={false} to skip this when the host already lazy-loads.
  • Height reservation — inactive shells use cached height or defaultHeight (240) so scrolling does not collapse.
  • Previous-data hydrationuseCuiResource can show the last persisted payload instantly, then revalidate.
  • TTL + stale-while-revalidatettl / staleTtl map to fresh / stale / expired; default mount policy is if-stale.
  • Scoped isolationnamespace + scopeKey partition both height and resource persistence (account / tenant / env).
  • Targeted invalidation — exact key, prefix (order matches order and order:…), or full clearScope().
  • SWR integration — wrap with SWRConfig + CuiKitProvider; invalidation also mutates the surrounding SWR cache.

Run the in-repo comparison: pnpm demo.

Install

pnpm add lor-cui-kit
pnpm add react swr

Peers: react ^18.2.0 || ^19.0.0, swr ^2.0.0. Engine: Node >=20.19.0. The package is ESM-only.

import { createCuiKit, CuiKitProvider, CuiCardShell, useCuiResource } from 'lor-cui-kit'
import { useCuiKit } from 'lor-cui-kit/react'
import { createMemoryStorageAdapter } from 'lor-cui-kit/core'

Quick start

1. Create CuiKit

const cuiKit = createCuiKit({
  namespace: 'agent-chat',
  scopeKey: `${environment}:${tenantId}:${userId}`,
  persistResources: true,
})

2. Provider

Give SWR an isolated Map per kit/session so invalidate does not leak across users.

<SWRConfig value={{ provider: () => new Map() }}>
  <CuiKitProvider value={cuiKit}>
    <Chat />
  </CuiKitProvider>
</SWRConfig>

3. CuiCardShell

<CuiCardShell cardKey={message.id}>
  <OrderCard orderId={orderId} />
</CuiCardShell>

Inactive shells render no children. Put useCuiResource inside the card, not around the shell, or every card will fetch.

4. useCuiResource

const { data, error, isLoading, isValidating, isStale } = useCuiResource({
  key: `order:${orderId}`,
  fetcher: () => getOrder(orderId),
  ttl: 30_000,
  staleTtl: 5 * 60_000,
  persist: true,
})

key: null disables the request (isLoading is false). Pass the same CuiKit instance to CuiKitProvider for the lifetime of that scopeKey.

TTL / staleTtl semantics

Each write stores expiresAt = now + ttl. Reads classify the entry:

| State | When | UI / fetch (default revalidateOnMount: 'if-stale') | | --- | --- | --- | | fresh | now < expiresAt | Show data. No fetch on mount. | | stale | expiresAt <= now < expiresAt + staleTtl | Show previous data. Background fetch. isStale === true. | | expired | now >= expiresAt + staleTtl | Entry is deleted. Treated as a miss; fetch if the hook is mounted. | | miss | no entry | Fetch. |

staleTtl defaults to the kit’s defaultStaleTtl (300_000 ms). Override per hook.

revalidateOnMount:

  • 'if-stale' (default) — fetch on miss / stale / expired, not on fresh.
  • 'always' — always fetch on mount.
  • false — never fetch on mount (manual revalidate()).

Failed late writes (generation changed by invalidate) are dropped; the hook keeps the latest cache payload.

Invalidation after writes / prefix invalidate

After a mutation, drop cache and tell SWR to refetch mounted hooks:

import { invalidateCuiResource, invalidateCuiPrefix, clearCuiScope } from 'lor-cui-kit'

await invalidateCuiResource(cuiKit, `order:${orderId}`)
await invalidateCuiPrefix(cuiKit, 'order')
await clearCuiScope(cuiKit)

Prefix match is key === prefix or key.startsWith(prefix + ':'). order matches order and order:42, not order-archive.

CuiKitProvider binds useSWRConfig().mutate so these helpers also update in-memory SWR keys. clearCuiScope clears height + resource persistence for the current namespace/scope and mutates matching SWR keys with { revalidate: false }. Call it on logout.

Height cache and layoutKey

CuiCardShell keys a height as (cardKey, layoutKey):

  • Omit layoutKey and the shell buckets content width into w100, w200, … (100px buckets) so desktop vs phone do not share one height.
  • Pass layoutKey yourself when width is not the right axis (for example 'compact' vs 'expanded').

Behavior:

  1. Inactive — CSS height = cached value or defaultHeight.
  2. Active, not yet measuredminHeight uses the same reservation.
  3. Measured — forced height is removed; a ResizeObserver on the inner content writes the cache.

Heights persist through the height storage adapter (localStorage by default), independently of persistResources.

scopeKey and account / tenant isolation

namespace is the product surface (agent-chat). scopeKey is the privacy and cache boundary. Recommended:

scopeKey: `${environment}:${tenantId}:${userId}`

Storage keys look like lor-cui-kit:v1:height:… and lor-cui-kit:v1:resource:…, namespaced with URI-encoded namespace and scopeKey. Two users on one browser profile do not share entries if scopeKey differs.

On account switch or logout:

await clearCuiScope(previousKit)

Then create a new CuiKit (and a new SWR Map) for the next scopeKey. Do not reuse a kit across users.

localStorage privacy warning

Default adapters write to window.localStorage in plaintext.

  • Heights are persisted even when persistResources is false.
  • Business payloads are persisted only when persistResources: true or the hook sets persist: true.
  • Keys include namespace, scopeKey, cardKey, and resource keys (for example order:42). Values are JSON of your fetcher result.
  • Anyone with device access, another script on the origin, or XSS can read this cache. Do not persist secrets, tokens, or regulated PII unless that risk is accepted.
  • Shared / kiosk browsers: always clearCuiScope on logout. For tests or no persistence, pass createMemoryStorageAdapter() as heightStorage / resourceStorage.
  • On the server there is no window; the localStorage adapter falls back to memory and useCuiResource forces persist: false.

SSR limitations

This kit is client-first. React entries are marked 'use client'.

  • Server CuiCardShell always uses defaultHeight (240). Cached heights are not read during renderToString (useSyncExternalStore server snapshot is undefined). With lazy (default), children are not rendered until the client observer activates the shell. With lazy={false}, children render immediately, including during SSR.
  • persist is false when typeof window === 'undefined'.
  • No IntersectionObserver → the shell activates after the ref attaches.
  • No ResizeObserver → height is measured once via getBoundingClientRect.
  • Hydration: expect the reserved 240px (or your defaultHeight) on the server HTML; the client may replace it with a cached height after paint. Avoid putting useCuiResource in a Server Component.

API Reference

Package exports

| Entry | Runtime | | --- | --- | | lor-cui-kit | createCuiKit, CuiKitProvider, CuiCardShell, useCuiResource, invalidateCuiResource, invalidateCuiPrefix, clearCuiScope, createLocalStorageAdapter, createMemoryStorageAdapter | | lor-cui-kit/react | Above React APIs plus useCuiKit, useCuiVisibility | | lor-cui-kit/core | createCuiKit, invalidation helpers, storage adapters |

createCuiKit(options)

| Option | Default | Notes | | --- | --- | --- | | namespace | required | Product / feature id. | | scopeKey | required | Account / tenant / env isolation. | | defaultHeight | 240 | Reserved height before measure. | | preloadMargin | '600px 0px' | IntersectionObserver rootMargin. | | defaultStaleTtl | 300_000 | Fallback staleTtl for reads. | | persistResources | false | Default for useCuiResource({ persist }). | | heightStorage | localStorage adapter | Implements StorageAdapter. | | resourceStorage | localStorage adapter | L2 write only when persist is true. | | now | Date.now | Inject for tests. | | onStorageError | — | Called when localStorage throws. |

effectivePersist(persist?) is persist ?? persistResources. Providing resourceStorage does not by itself persist; the hook/persistResources flag must be true.

CuiCardShell

| Prop | Default | Notes | | --- | --- | --- | | cardKey | required | Stable id (message id). | | layoutKey | auto w{bucket} | Width bucket of 100px, or your own key. | | keepMounted | true | Once activated, stay mounted when leaving the viewport. Ignored when lazy is false. | | lazy | true | Observe the viewport and mount children only when intersecting. Set false if the host already lazy-loads cards. | | className | — | Applied to the outer shell. | | children | required | Mounted only while active, or immediately when lazy is false. |

useCuiResource(options)

Must run under CuiKitProvider.

| Option | Default | Notes | | --- | --- | --- | | key | required | Logical key, or null to pause. | | fetcher | required | () => Promise<T>. | | ttl | required | Fresh window in ms. | | staleTtl | kit defaultStaleTtl | Stale window after ttl. | | persist | kit persistResources | Forced false without window. | | revalidateOnMount | 'if-stale' | 'always' | 'if-stale' | false. | | dedupeInterval | 2000 | SWR dedupingInterval. | | keepPreviousData | true | SWR option. |

Result: data, error, isLoading, isValidating, isStale, updatedAt, revalidate().

Invalidation helpers

invalidateCuiResource(kit, key)
invalidateCuiPrefix(kit, prefix)
clearCuiScope(kit)

Each takes an explicit CuiKit. There is no global singleton.

StorageAdapter

interface StorageAdapter {
  getItem(key: string): string | null
  setItem(key: string, value: string): void
  removeItem(key: string): void
  keys(): Iterable<string>
}

License: MIT.