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

@iblai/data-layer

v1.1.2

Published

ibl.ai data layer

Readme

@iblai/data-layer

A Redux Toolkit-based data layer package for IBL AI applications, providing centralized state management and API integrations using RTK Query.

Installation

pnpm add @iblai/data-layer

Overview

The data-layer package provides:

  • RTK Query API slices for all IBL AI API endpoints
  • Redux store configuration with pre-configured slices
  • Type-safe API hooks for React components
  • Centralized state management for auth, chat, subscriptions, and more

Getting Started

1. Setup Redux Store

Wrap your application with the Redux Provider:

import { Provider } from 'react-redux';
import { store } from '@iblai/data-layer';

function App() {
  return (
    <Provider store={store}>
      <YourApp />
    </Provider>
  );
}

2. Using API Hooks

The package provides auto-generated hooks for all API endpoints:

import { useGetUserProfileQuery, useUpdateUserProfileMutation } from '@iblai/data-layer';

function UserProfile() {
  // Query hook - automatically fetches data
  const { data: profile, isLoading, error } = useGetUserProfileQuery();

  // Mutation hook - for updates
  const [updateProfile, { isLoading: isUpdating }] = useUpdateUserProfileMutation();

  const handleSave = async (data) => {
    await updateProfile(data).unwrap();
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>{profile.name}</h1>
      {/* Your profile UI */}
    </div>
  );
}

Available API Slices

Core APIs

import {
  // User & Auth
  useGetUserProfileQuery,
  useUpdateUserProfileMutation,
  useLoginMutation,

  // Tenants
  useGetTenantsQuery,
  useGetTenantQuery,
  useCreateTenantMutation,

  // Platform
  useGetPlatformConfigQuery,
} from '@iblai/data-layer';

AI & Chat APIs

import {
  // Mentors
  useGetMentorsQuery,
  useGetMentorQuery,
  useCreateMentorMutation,

  // Chat Sessions
  useGetChatSessionsQuery,
  useCreateChatSessionMutation,

  // Memory
  useGetMemoriesQuery,
  useCreateMemoryMutation,
} from '@iblai/data-layer';

Subscription APIs

import {
  // Stripe Integration
  useGetSubscriptionQuery,
  useCreateCheckoutSessionMutation,
  useCreateCustomerPortalSessionMutation,

  // Pricing
  useGetPricingPlansQuery,
} from '@iblai/data-layer';

Features

Automatic Caching

RTK Query automatically caches API responses and handles cache invalidation:

// This query result is cached
const { data } = useGetUserProfileQuery();

// Subsequent calls use cached data
const { data: sameData } = useGetUserProfileQuery(); // No network request

Optimistic Updates

const [updateProfile] = useUpdateUserProfileMutation();

const handleUpdate = async (newData) => {
  try {
    await updateProfile({
      id: userId,
      ...newData,
    }).unwrap();
    // UI updates optimistically before API response
  } catch (error) {
    // Error handling
  }
};

Manual Cache Invalidation

import { useDispatch } from 'react-redux';
import { apiSlice } from '@iblai/data-layer';

function RefreshButton() {
  const dispatch = useDispatch();

  const handleRefresh = () => {
    // Invalidate specific tags
    dispatch(apiSlice.util.invalidateTags(['User']));

    // Or reset entire API state
    dispatch(apiSlice.util.resetApiState());
  };

  return <button onClick={handleRefresh}>Refresh</button>;
}

Polling

// Poll every 5 seconds
const { data } = useGetChatSessionsQuery(undefined, {
  pollingInterval: 5000,
});

Conditional Fetching

// Only fetch when userId is available
const { data } = useGetUserProfileQuery(userId, {
  skip: !userId,
});

Store Structure

The store includes the following slices:

{
  api: RTKQueryState,           // All API data
  auth: AuthState,              // Authentication state
  chat: ChatState,              // Chat sessions and messages
  files: FilesState,            // File uploads and attachments
  subscription: SubscriptionState, // Subscription info
}

Accessing Store State

import { useSelector } from 'react-redux';
import { selectIsLoggedIn, selectCurrentUser } from '@iblai/data-layer';

function Header() {
  const isLoggedIn = useSelector(selectIsLoggedIn);
  const user = useSelector(selectCurrentUser);

  return (
    <header>
      {isLoggedIn ? `Welcome ${user.name}` : 'Please log in'}
    </header>
  );
}

TypeScript Support

All APIs are fully typed:

import type { UserProfile, Tenant, Mentor } from '@iblai/data-layer';

const { data } = useGetUserProfileQuery();
// data is typed as UserProfile | undefined

const { data: tenant } = useGetTenantQuery(tenantId);
// tenant is typed as Tenant | undefined

Error Handling

const { data, error, isError } = useGetUserProfileQuery();

if (isError) {
  if ('status' in error) {
    // RTK Query error
    const errMsg = 'error' in error ? error.error : JSON.stringify(error.data);
    return <div>Error: {errMsg}</div>;
  } else {
    // Serialized error
    return <div>Error: {error.message}</div>;
  }
}

Advanced Usage

Custom Endpoints

Extend the API slice with custom endpoints:

import { apiSlice } from '@iblai/data-layer';

const extendedApi = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    getCustomData: builder.query({
      query: () => '/custom-endpoint',
    }),
  }),
});

export const { useGetCustomDataQuery } = extendedApi;

Prefetching

import { useDispatch } from 'react-redux';
import { apiSlice } from '@iblai/data-layer';

function PrefetchExample() {
  const dispatch = useDispatch();

  const prefetchUserProfile = () => {
    dispatch(
      apiSlice.util.prefetch('getUserProfile', userId, { force: true })
    );
  };

  return <button onMouseEnter={prefetchUserProfile}>Hover to prefetch</button>;
}

Contributing

We welcome contributions! Please read our contributing guidelines.

Development

Local Development Setup

When developing locally, use a local registry to publish packages:

make publish-local

Configure your .npmrc:

//localhost:4873/:_authToken=<token>
@iblai:registry=http://localhost:4873/

Building

pnpm build

Testing

pnpm test

License

ISC