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

@primocaredentgroup/chat-ui

v2.1.4

Published

Typed API references, shared types, and React utilities for PrimoUp chat orchestrator

Downloads

706

Readme

@primocaredentgroup/chat-ui

Shared frontend utilities for PrimoUp and PrimoLab. The package contains typed Core API references, presentation types, React hooks for authenticated Lab actions, and a Convex client context. It does not contain the complete chat widget, patient permissions, backend domain logic, or service credentials.

The backend is @primocaredentgroup/chat-backend-component, mounted only in PrimoUpCore as primoChat. The visible chat panels remain in each product's src/components/chat directory.

Entry points

| Import | Contents | | --- | --- | | @primocaredentgroup/chat-ui | Core API references, complete Core types, React helpers and provider | | …/orchestrator, …/advanced, …/primocheckBridge | Typed references to Core's public functions | | …/types | Complete Core response/argument types; opaque string IDs | | …/presentation | Minimal shapes rendered by either host | | …/react | Action query/mutation hooks, explicit SLA clock and per-adapter refresh scope | | …/bridge | Shared server wire validators; requires backend component 0.3.2, without mounting another Chat instance | | …/provider | Context for a host-owned Convex client |

PrimoUp: realtime on the existing authenticated client

import { useQuery } from "convex/react";
import { chatOrchestrator } from "@primocaredentgroup/chat-ui/orchestrator";
import { useChatClock } from "@primocaredentgroup/chat-ui/react";

const messages = useQuery(chatOrchestrator.listMessagesFiltered,
  authenticated && threadId ? { subchannelId: threadId } : "skip");
const now = useChatClock(30_000);

Authentication and resource permissions are enforced by the Core handlers. References exported from /orchestrator, /advanced and /primocheckBridge target Core, not the Lab deployment.

PrimoLab: host adapter and authenticated server bridge

Lab supplies references from its own generated api.api.primoUpChatBridge. The shared library does not import another repository's generated API or construct cross-deployment URLs.

import {
  createChatRefreshScope, useChatActionQuery, useChatActionMutation,
} from "@primocaredentgroup/chat-ui/react";
import { api } from "./convex/_generated/api";

// Create once, outside render, in the application's adapter.
const refreshScope = createChatRefreshScope();

function useMessages(threadId: string, serverResolvedUserKey: string | null) {
  return useChatActionQuery(api.api.primoUpChatBridge.listMessagesFiltered,
    { subchannelId: threadId }, { sessionKey: serverResolvedUserKey, refreshScope });
}

Use the authenticated host query to obtain the user key. An absent identity or "skip" disables reads and hides cached data. Reads refresh every 15 seconds while visible, on focus, after visibility changes and after successful writes through useChatActionMutation with the same refresh scope. In-flight reads coalesce refreshes. Responses from old arguments, old sessions or unmounted components are ignored. Read errors reach the host's error boundary; it owns localized error and retry UI.

A refresh scope belongs to one application adapter. It is not a window-global event. Core may keep its native realtime queries; Lab's action polling is not a cross-deployment websocket subscription.

Client ownership

Prefer the host's existing authenticated client:

<ChatConvexProvider client={hostClient}>{children}</ChatConvexProvider>

The package neither changes that client's authentication nor closes it. The legacy convexUrl + authToken props remain only for existing Core integrations; their owned clients now close on unmount and token/URL changes, including React StrictMode. The token is never logged or exposed through the context. Do not use this legacy mode in Lab: Lab authenticates its own client and calls Core exclusively from its backend.

2.1.2 integration

  • Adds shared Lab/Core wire validators at /bridge (backend peer ^0.3.2). Hosts that import this server entrypoint install @primocaredentgroup/chat-backend-component explicitly.
  • Adds listPatientChats with Convex pagination, pending-treatment counts and clinic IDs. Widget unread totals take { now, clinicId? }.
  • Patient structures support a missing fiscal code. Lab matching still requires the canonical fiscal-code/prescription mapping.
  • Core uses the existing realtime client; Lab uses only authenticated actions on its own client. No VITE_CONVEX_URL_CHAT is needed.

Contract corrections in 2.1.1

  • Upload requires { subchannelId }; downloading an attachment requires { storageId, messageId }.
  • SLA preview accepts now, supplied by the UI clock.
  • PrimoCheck uses the real revealMessageAuthor endpoint; the former getMessageRealAuthor export is a deprecated alias to it.
  • PrimoCheck channel creation returns { channelId, subchannelId }; send operations return null.
  • Added references for PrimoCheck chat info and authorized attachment upload.

Existing clients should recompile against these corrected contracts. The backend decides user identity, roles, side and resource scope; frontend types do not grant access.

Development and release

Source of truth: PrimoUpCore/packages/chat-ui. Do not maintain a second implementation in primoLabCoreV2/vendor/chat-ui. Lab keeps only its adapter to generated APIs and imports the published package.

npm ci
npm run verify
npm pack --dry-run

Tests cover session isolation, late responses, conversation changes, polling lifecycle, write-triggered refresh and client ownership. Both hosts should consume the same exact published version in their manifests and lockfiles. Package build and tests do not replace host typechecks and browser integration checks.

GitHub Actions validates package changes with React 18 and 19. publish-chat-ui.yml runs on relevant main changes or manual dispatch and publishes through npm Trusted Publishing/OIDC. Configure its GitHub publisher as organization primocaredentgroup, repository PrimoUpCore, workflow filename publish-chat-ui.yml, no environment, with direct publishing allowed. This existing package retains public npm access.

An unchanged committed version receives one automatic patch commit updating both manifests. An explicit stable version increase is preserved; downgrades and prereleases are rejected. The job checks the current remote head before publishing, publishes the verified tarball, compares registry integrity and latest, and installs a fresh consumer. An existing immutable version is accepted only if its integrity matches. A failed run can be retried without inventing another version. Release artifacts are retained even if the registry verification fails. This workflow does not deploy either host application.