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

@fluxyte/sdk

v0.8.1

Published

Official Fluxyte SDK (TypeScript) for the Fluxyte Onboarding AI API

Readme

Fluxyte SDK (TypeScript)

The official TypeScript SDK for the Fluxyte Onboarding AI API: a context-aware, documentation-grounded assistant designed for onboarding and setup flows (not generic chat).

Unreleased

  • Chat and voice now use top-level sessionId or userId; their context is optional.
  • PublicChatContext contains only validated catalogue/step hints, diagnostics, runtime metadata, locale, and timezone.
  • Structured error and attemptedAction objects provide richer troubleshooting context.
  • Named public context, request, response, diagnostic, and event types are exported from all entrypoints.

What's New In 0.7.0

  • Product Catalogue offering cards now expose optional imageAlt and videoUrl fields.
  • Use imageAlt when rendering catalogue images and open videoUrl as a validated hosted-video destination.
  • Existing imageUrl, pricing, availability, and Commerce action fields remain backward compatible.
const response = await client.chat({
  message: "Show me your plans",
  sessionId: "session_123",
});

for (const offering of response.commerce?.offerings ?? []) {
  console.log(offering.imageUrl, offering.imageAlt, offering.videoUrl);
}

What's New In 0.6.0

  • Product Catalogue responses now include typed commerce presentation data.
  • Commerce presentations contain products/services offerings, prices, availability, features, and safe action IDs.
  • openCommerceAction() resolves an external checkout only after the API validates the organization, plan, catalogue publication, offering availability, and action.
  • useStreamingChat() now exposes both commerce and resources from the completed response.

What's New In 0.5.0

  • Structured resources are available on chat, streaming, and voice responses.
  • Supported resource kinds: VIDEO, AUDIO, STORE, REDIRECT, REFERRAL, and CHECKOUT.
  • Video and audio resources can include a safe embedUrl for inline rendering.
  • useStreamingChat() now exposes the completed response's resources.

Install

npm install @fluxyte/sdk

Requirements

  • Browser or Node.js 18+ (global fetch available)
  • A Fluxyte API key (sent as X-API-Key)
    • pk_* for browser/public SDK usage
    • sk_* for backend/server usage only

Authentication (API Key)

Treat your API key like a password. Do not commit it to source control.

Create an API key

  1. Sign up at https://fluxyte.com/signup
  2. Verify your email
  3. Open the Account menu
  4. Select API Keys
  5. Click Create API Key
  6. Choose key type:
    • pk_* (PUBLIC) for frontend/browser SDK usage
    • sk_* (SECRET) for backend/server-only usage
  7. Copy your API key (shown once)

Use an API key

All integrations authenticate with an API key sent in the X-API-Key header.

  • Use pk_* keys in browser/public SDK integrations
  • Use sk_* keys only in backend/server environments
  • For pk_* keys, configure allowed origins to restrict frontend domains
  • The key controls organization access, docs scope, and analytics ownership

Environment examples

  • Vite: VITE_FLUXYTE_API_KEY=pk_...
  • Next.js: NEXT_PUBLIC_FLUXYTE_API_KEY=pk_... (public key only)
  • Server: FLUXYTE_API_KEY=sk_...

The SDK rejects sk_* keys in browser environments to prevent accidental exposure.

Key Management

Key Purpose

  • pk_* (PUBLIC): for browser/frontend SDK usage.
  • sk_* (SECRET): for backend/server usage only.

How to get keys

  1. Sign in to Fluxyte dashboard.
  2. Go to Account -> API Keys.
  3. Create a key and choose type:
    • PUBLIC (pk_*) for frontend SDK traffic.
    • SECRET (sk_*) for backend automation or server integrations.
  4. Copy the key immediately (shown once).

Allowed origins (PUBLIC keys)

For pk_* keys, configure allowed origins in dashboard (for example https://app.example.com). This limits where browser-based SDK requests are accepted from.

Rotation and revocation

  • Rotate keys on a regular schedule (recommended every 60-90 days).
  • Keep a short overlap window where old and new keys are both valid during rollout.
  • Revoke keys immediately if exposed.
  • Update environment variables and redeploy clients after rotation.

Environment examples

  • Frontend: NEXT_PUBLIC_FLUXYTE_API_KEY=pk_...
  • Backend: FLUXYTE_API_KEY=sk_...

Never expose sk_* in browser bundles, client logs, or public repos.

Choose An Entrypoint

The SDK ships multiple entrypoints, all with the same API surface:

  • @fluxyte/sdk/react (React hooks + provider)
  • @fluxyte/sdk/node (server-side; validates fetch availability)
  • @fluxyte/sdk/vanilla (browser usage without React)
  • @fluxyte/sdk (base exports)

Create A Client (Node / Vanilla)

import { OnboardingAIClient } from "@fluxyte/sdk/node";

const client = new OnboardingAIClient(process.env.FLUXYTE_API_KEY!);

Client Options (Session Handling)

The SDK enforces stable identity. Chat and voice accept top-level sessionId or userId; onboarding events retain identity inside their event context.

  • By default, it auto-generates and reuses sessionId when missing.
  • You can disable this with autoSessionId: false.
const client = new OnboardingAIClient(process.env.FLUXYTE_API_KEY!, {
  autoSessionId: true, // default
  sessionStorageKey: "fluxyte_onboarding_session_id", // browser storage key
});

Chat Completions (Non-Streaming)

const res = await client.chat({
  message: "How do I connect my database?",
  sessionId: "sess_123",
  context: {
    stepSlug: "connect_database",
    pageUrl: "https://app.example.com/setup/database",
  },
});

console.log(res.answerId);
console.log(res.reply);
console.log(res.confidence);
console.log(res.sources);
console.log(res.resources);
console.log(res.commerce);

Product Catalogue and Commerce

When an organization has published catalogue items and its plan includes Commerce, chat responses may include a structured presentation alongside the natural-language reply:

for (const offering of res.commerce?.offerings ?? []) {
  console.log(offering.name);
  console.log(offering.priceAmountMinor, offering.currency);
  console.log(offering.availability);
  console.log(offering.features);
  console.log(offering.actions);
}

if (res.commerce?.hasMore) {
  // Send a normal semantic continuation, such as "Show me more".
}

The API returns at most five offerings for catalogue discovery at a time. Do not implement client-side slicing or infer the next page; send the user's semantic continuation so the server can advance durable Commerce state.

Catalogue actions are typed as:

  • EXTERNAL_CHECKOUT — resolve through openCommerceAction().
  • REQUEST_QUOTE — send the action label/intention through chat.
  • CONTACT_SALES — send the action label/intention through chat.

Only external checkout is a redirect. Never construct or cache checkout URLs from catalogue data. Resolve the selected action immediately before navigation:

const action = offering.actions.find(
  (candidate) => candidate.kind === "EXTERNAL_CHECKOUT",
);

if (action) {
  const redirect = await client.openCommerceAction(action.id, "sess_123");
  if (redirect.kind === "REDIRECT") {
    window.location.assign(redirect.url);
  }
}

Rich Content Resources

When approved knowledge or a flow step includes a related resource, the response can contain:

type ContentResource = {
  id: string;
  kind: "VIDEO" | "AUDIO" | "STORE" | "REDIRECT" | "REFERRAL" | "CHECKOUT";
  url: string;
  label: string;
  embedUrl?: string | null;
};

Use url for links and actions. Use embedUrl only when it is present; it is the server-approved URL intended for an embedded video or audio player.

for (const resource of res.resources ?? []) {
  if (resource.embedUrl) {
    renderEmbeddedMedia(resource.embedUrl, resource.label);
  } else {
    renderResourceLink(resource.url, resource.label);
  }
}

Chat Completions (Streaming via SSE)

Streaming is useful when you want:

  • live typing UX
  • progressive rendering
  • early access to answerId (for feedback)

Streaming lifecycle:

  1. meta (contains answerId)
  2. delta (partial text; one or more)
  3. done (confidence, sources, resources, commerce)
const stop = client.streamChat(
  {
    message: "What's the next step?",
    sessionId: "sess_123",
    context: { stepSlug: "connect_database" },
  },
  (event) => {
    if (event.type === "meta") console.log("Answer ID:", event.answerId);
    if (event.type === "delta") process.stdout.write(event.replyDelta);
    if (event.type === "done") {
      console.log("\nConfidence:", event.confidence);
      console.log("Sources:", event.sources);
      console.log("Resources:", event.resources);
      console.log("Commerce:", event.commerce);
    }
  },
  (err) => {
    // Optional: handle auth/network/server errors.
    console.error("Streaming error:", err);
  },
);

// stop() cancels streaming

Voice Chat (Speech In + Optional Speech Out)

const voice = await client.voiceChat({
  audioBase64: "BASE64_AUDIO",
  mimeType: "audio/webm",
  userId: "user_123",
  context: { stepSlug: "connect_database", locale: "en-NG" },
  synthesize: true,
  voice: "alloy",
  audioFormat: "mp3",
});

console.log(voice.transcript); // text recognized from audio
console.log(voice.reply); // AI text reply
console.log(voice.replyAudioBase64); // optional synthesized voice
console.log(voice.resources); // approved related links or embedded media

Context

Context is optional for chat and voice requests. Identity is separate and required; the SDK auto-generates a reusable sessionId unless autoSessionId is disabled.

type PublicChatContext = {
  catalogueSubjectId?: string;
  stepSlug?: string;
  endpoint?: string;
  pageUrl?: string;
  error?: {
    code?: string;
    description?: string;
    field?: string;
    source?: "client" | "server" | "network" | "third_party";
    httpStatus?: number;
    retryable?: boolean;
  };
  attemptedAction?: {
    name: string;
    description?: string;
    target?: string;
    status?: "started" | "blocked" | "failed" | "completed";
  };
  sdk?: "react" | "node" | "vanilla" | "rest";
  sdkVersion?: string;
  appVersion?: string;
  environment?: "development" | "staging" | "production";
  locale?: string;
  timezone?: string;
};

Best practices:

  • Pass catalogueSubjectId when the customer is viewing a published product or service.
  • Pass stepSlug when the customer is inside a published onboarding step.
  • Keep sessionId and userId at the request's top level, outside context.
  • Treat context like application state (update it as the user moves)
  • For task assistance or troubleshooting, pass non-secret diagnostic context when known

Identity guidance:

  • Anonymous visitors: let SDK auto-manage sessionId or pass your own persisted ID.
  • Logged-in users: pass a stable top-level userId.

Localization & Timezone

Pass optional localization and timezone fields so the API can tailor user-facing formatting and time-aware utility responses:

context: {
  locale: "en-US",        // browser/client locale for user-facing formatting
  timezone: "Africa/Lagos", // IANA timezone for the current user
}
  • locale — browser/client locale (for example en-US, en-NG) used for user-facing formatting.
  • timezone — IANA timezone for the current user (for example America/New_York, Africa/Lagos, Europe/London).

Task and troubleshooting context

The public assistant can use structured context to understand the user's current task and troubleshoot with fewer clarification turns. Pass only non-secret values:

await client.chat({
  message: "I get a 401 when I send my first message",
  userId: "user_123",
  context: {
    sdk: "react",
    sdkVersion: "0.8.0",
    appVersion: "2026.08.30",
    environment: "production",
    endpoint: "/v1/chat/completions",
    pageUrl: "https://app.example.com/setup/chat",
    error: {
      code: "AUTHENTICATION_FAILED",
      description: "The first chat request returned 401 after the user saved their public API key.",
      source: "server",
      httpStatus: 401,
      retryable: false,
    },
    attemptedAction: {
      name: "send_first_chat_message",
      description: "Send the first message from the React setup screen.",
      target: "Public AI chat",
      status: "failed",
    },
  },
});
  • sdk identifies the client or entrypoint in use.
  • sdkVersion identifies the Fluxyte SDK version and appVersion the integrating app.
  • environment is development, staging, or production.
  • endpoint identifies the affected API route or operation.
  • error carries structured, customer-safe diagnostics, including a comprehensive description.
  • attemptedAction describes the action, target, and outcome without duplicating the user's message.

Do not put API keys, access tokens, passwords, request bodies containing personal data, or other secrets in context.

Onboarding Events

Events power onboarding analytics, drop-off detection, and AI insights.

Supported event types:

  1. FLOW_STARTED
  • User begins a tracked onboarding flow.
  • Send once when the flow is entered.
  1. STEP_VIEWED
  • User lands on or opens a specific step.
  • Send whenever the current step changes.
  1. STEP_COMPLETED
  • User successfully completes a step.
  • Send only after verified completion signal.
  1. FLOW_COMPLETED
  • User completes all required steps in the flow.
  • Send once at successful finish.
  1. ABANDONED
  • User exits/stalls before completion.
  • Send when inactivity timeout or explicit exit indicates drop-off.

Recommended minimum context for event quality:

  • flowId
  • stepId (for step-level events)
  • stable identity (context.sessionId or context.userId)

Typical event sequence:

  1. FLOW_STARTED
  2. STEP_VIEWED (step 1)
  3. STEP_COMPLETED (step 1)
  4. STEP_VIEWED (step 2)
  5. STEP_COMPLETED (step 2)
  6. FLOW_COMPLETED

Drop-off sequence example:

  1. FLOW_STARTED
  2. STEP_VIEWED (step 1)
  3. STEP_VIEWED (step 2)
  4. ABANDONED
await client.sendEvent({
  type: "STEP_COMPLETED",
  context: {
    flowId: "premium-support-setup",
    stepId: "connect-database",
    userId: "customer_123",
  },
});

Feedback

await client.submitFeedback({
  answerId: "ans_7xk9p2m",
  rating: "GOOD",
  comment: "Clear explanation and actionable advice",
});

React Usage (Recommended)

import { OnboardingAIClient } from "@fluxyte/sdk";
import { OnboardingAIProvider } from "@fluxyte/sdk/react";

const client = new OnboardingAIClient(import.meta.env.VITE_FLUXYTE_API_KEY);

export function App() {
  return (
    <OnboardingAIProvider client={client}>
      {/* your app */}
    </OnboardingAIProvider>
  );
}

React Hooks

import { useChat } from "@fluxyte/sdk/react";

const { send, data, loading, error } = useChat();

await send({
  message: "How do I connect my database?",
  sessionId: "sess_123",
  context: { stepSlug: "connect_database" },
});
import { useStreamingChat } from "@fluxyte/sdk/react";

const { text, answerId, confidence, resources, commerce, streaming, start, stop } =
  useStreamingChat();

start({
  message: "What's the next step?",
  context: { stepSlug: "connect_database" },
});
import { useVoiceChat } from "@fluxyte/sdk/react";

const { sendVoice, loading, data, error } = useVoiceChat();

const res = await sendVoice({
  audioBase64: "BASE64_AUDIO",
  mimeType: "audio/webm",
  context: { stepSlug: "connect_database" },
  synthesize: true,
  voice: "alloy",
  audioFormat: "mp3",
});

console.log(res.transcript);
console.log(res.reply);

Multi-Target

Use context.product or context.service to isolate onboarding targets under one account (apps, APIs, and services).

Error Handling

import { APIError } from "@fluxyte/sdk";

try {
  await client.chat(/* ... */);
} catch (err) {
  if (err instanceof APIError) {
    console.error(err.status, err.message);
  }
}

License

Commercial. See LICENSE.md.