The @paritydeals/react-sdk provides a seamless way to integrate ParityDeals entitlement management into your React applications.

Overview

  • A React Context Provider (ParityDealsProvider) to initialize and configure the SDK.
  • Hooks to easily access entitlement status and data within your components.
  • Conditional rendering components to show or hide UI elements based on feature access.
  • Automatic and manual data fetching and caching mechanisms.

The SDK fetches all entitlements for a given organization and customer, caches them, and makes them available throughout your application via React Context and custom hooks.

2. Installation

Install the SDK using npm or yarn:

npm install @paritydeals/react-sdk
# or
yarn add @paritydeals/react-sdk

You will also need react as a peer dependency.

3. Setup & Configuration

ParityDealsProvider

The core of the SDK is the ParityDealsProvider. You need to wrap your application (or the relevant part of it) with this provider. It initializes the SDK and makes entitlement data available to its children components via context.

// In your App.tsx or main application entry point
import React from 'react';
import { ParityDealsProvider } from '@paritydeals/react-sdk';

const App = () => {
  return (
    <ParityDealsProvider
      customerId="your-customer-id"
      accessToken="your-access-token"
    >
      <MyAppContent />
    </ParityDealsProvider>
  );
};

const MyAppContent = () => {

  return (
    <div>
      <h1>My Application</h1>
    </div>
  );

};

export default App;

Required Props for ParityDealsProvider

  • customerId: string
    • The ID of the customer for whom entitlements are being fetched. This will be sent as a query parameter (customer_id).
  • accessToken: string | null
    • Your static API token or Bearer token for authenticating requests to the ParityDeals API. If provided, it will be included in the Authorization: Bearer <accessToken> header.

Optional Props for ParityDealsProvider

4. Fetching Entitlements

Automatic Fetching on Mount

By default (fetchEntitlementsOnMount: true in the config prop, or if config or this specific option is omitted), the SDK will attempt to fetch all entitlements for the specified customerId as soon as the ParityDealsProvider is mounted.

The isLoading state from useParityDeals() will be true during this initial fetch.

Manual Fetching

If fetchEntitlementsOnMount is set to false, or if you need to re-fetch entitlements at any point (e.g., after a user action that might change their entitlements), you can use the refreshAllEntitlements function.

5. Accessing Entitlement Data (Hooks)

The SDK provides several hooks to access entitlement data and SDK state.

useParityDeals()

This is the primary hook to access the SDK’s context.

  • Returns: ParityDealsContextValue object containing:
    • allEntitlements: AsyncState<EntitlementMap | null>: The state object for all fetched entitlements.
      • data: An EntitlementMap (a Record<string, AnyEntitlement>) where keys are featureKeys, or null if not loaded or error.
      • isLoading: Boolean indicating if the allEntitlements data is currently being fetched/refreshed.
      • error: An Error object if the last fetch failed, otherwise null.
    • refreshAllEntitlements: () => Promise<void>: Function to manually trigger a re-fetch of all entitlements.
    • getEntitlement: <T extends AnyEntitlement>(featureKey: string, type: T['type']) => AsyncState<T | null>: Function to get a specific entitlement’s state from the cache.
    • hasAccess: (featureKey: string) => boolean | undefined: A utility function to quickly check access for a feature. Returns true if access is granted, false if denied or feature not found, and undefined if data is loading or an error occurred.
    • isLoading: boolean: A global loading state indicating if the SDK is performing its initial configured fetch or a refresh operation.
    • error: Error | null: A global error state reflecting any error from the last fetch operation initiated by the provider.
    • customerId: string: The customer ID passed to the provider.
    • apiUrl: string: The base API URL passed to the provider.
    • entitlementsPath: string: The entitlements path passed to the provider.

useAllEntitlements()

A convenience hook that directly returns the allEntitlements state object.

  • Returns: AsyncState<EntitlementMap | null>
import { useAllEntitlements } from '@paritydeals/react-sdk';

function EntitlementsList() {
  const { data: entitlementsMap, isLoading, error } = useAllEntitlements();

  if (isLoading) return <p>Loading all entitlements...</p>;
  if (error) return <p>Error loading entitlements: {error.message}</p>;
  if (!entitlementsMap) return <p>No entitlements data.</p>;

  return (
    <ul>
      {Object.values(entitlementsMap).map(ent => (
        <li key={ent.featureKey}>
          {ent.featureKey}: {ent.hasAccess ? 'Enabled' : 'Disabled'} ({ent.type})
        </li>
      ))}
    </ul>
  );
}

useBooleanEntitlement(featureKey: string)

Fetches the state for a specific boolean entitlement from the cache.

  • Arguments:
    • featureKey: string: The key of the boolean feature.
  • Returns: AsyncState<BooleanEntitlement | null>

useConfigEntitlement(featureKey: string)

Fetches the state for a specific configuration entitlement from the cache.

  • Arguments:
    • featureKey: string: The key of the configuration feature.
  • Returns: AsyncState<ConfigEntitlement | null> (where ConfigEntitlement has a configuration: number | null property).

useMeteredEntitlement(featureKey: string)

Fetches the state for a specific metered entitlement from the cache.

  • Arguments:
    • featureKey: string: The key of the metered feature.
  • Returns: AsyncState<MeteredEntitlement | null>

Example using a specific entitlement hook:

import { useBooleanEntitlement } from '@paritydeals/react-sdk';

function FeatureSpecificComponent({ featureKey }: { featureKey: string }) {
  const { data: entitlement, isLoading, error } = useBooleanEntitlement(featureKey);

  if (isLoading) return <p>Loading feature {featureKey}...</p>;
  if (error) return <p>Error loading feature {featureKey}: {error.message}</p>;

  if (entitlement && entitlement.hasAccess) {
    return <p>You have access to {featureKey}!</p>;
  } else {
    return <p>You do not have access to {featureKey}.</p>;
  }
}

6. Conditional Rendering Components

These components provide a declarative way to render UI based on entitlement status. They internally use the respective hooks.

Common Props:

  • featureKey: string: The unique key of the feature to check.
  • children: ReactNode | ((data: E) => ReactNode):
    • If a ReactNode, it’s rendered when the user is entitled and conditions are met.
    • If a function (render prop), it’s called with the entitlement data (BooleanEntitlement, ConfigEntitlement, or MeteredEntitlement) and its return value is rendered.
  • fallback?: ReactNode: Content to render if the user is not entitled, or if data is loading (and no loadingComponent is provided), or if an error occurs. Defaults to null.
  • loadingComponent?: ReactNode: Specific content to render while the entitlement data is loading. Overrides fallback during loading.

ShowWhenBooleanEntitled

Renders children if the boolean feature is enabled (hasAccess: true).

import { ShowWhenBooleanEntitled } from '@paritydeals/react-sdk';

<ShowWhenBooleanEntitled
  featureKey="enable-dark-mode"
  loadingComponent={<p>Checking theme settings...</p>}
  fallback={<p>Dark mode is not available.</p>}
>
  <button>Toggle Dark Mode</button>
</ShowWhenBooleanEntitled>

<ShowWhenBooleanEntitled featureKey="show-advanced-settings">
  {(entitlementData) => (
    <div>Advanced settings for {entitlementData.featureKey} are visible!</div>
  )}
</ShowWhenBooleanEntitled>

ShowWhenConfigEntitled

Renders children if the config feature is enabled and provides the numeric configuration value to the children render prop.

  • Children Prop: (config: number) => ReactNode (Required to be a function for this component).
import { ShowWhenConfigEntitled } from '@paritydeals/react-sdk';

<ShowWhenConfigEntitled
  featureKey="max-items-per-page"
  loadingComponent={<p>Loading display settings...</p>}
  fallback={<p>Default item limit applies.</p>}
>
  {(maxItems) => <p>You can display up to {maxItems} items per page.</p>}
</ShowWhenConfigEntitled>

ShowWhenMeteredEntitled

Renders children if the metered feature is enabled and, by default, if remaining usage is greater than 0 or unlimited (limit is null).

  • Optional Prop:
    • condition?: (data: MeteredEntitlement) => boolean: A custom function to further determine if children should render based on the metered entitlement data.
  • Children Prop: Can be ReactNode or (data: MeteredEntitlement) => ReactNode.
import { ShowWhenMeteredEntitled } from '@paritydeals/react-sdk';

<ShowWhenMeteredEntitled
  featureKey="api-calls-quota"
  loadingComponent={<p>Loading API quota...</p>}
  fallback={<p>API call limit reached or feature not available.</p>}
>
  {(meterData) => (
    <div>
      <p>API Calls Used: {meterData.used} / {meterData.limit === null ? 'Unlimited' : meterData.limit}</p>
      <p>Remaining: {meterData.remaining === null ? 'Unlimited' : meterData.remaining}</p>
    </div>
  )}
</ShowWhenMeteredEntitled>

7. Key Types

The SDK exports several types for better integration with TypeScript. Some key ones include:

  • ParityDealsProviderOptions: Configuration for the provider.
  • ParityDealsContextValue: The shape of the object returned by useParityDeals().
  • AsyncState<T>: Generic type for asynchronous data states.
  • EntitlementMap: The structure of the cached entitlements (Record<string, AnyEntitlement>).
  • Entitlement, BooleanEntitlement, ConfigEntitlement, MeteredEntitlement: Processed entitlement types.
  • ApiRequestConfig, ApiResponse: Interfaces related to the underlying apiRequest service.
  • RawEntitlementsApiResponse and related Raw... types: Represent the structure of the direct API response.

You can import these types from @paritydeals/react-sdk/types (assuming your src/types/index.ts re-exports them) or directly from the main SDK entry if configured.

8. Error Handling

  • Provider Level: The onError callback in ParityDealsProviderOptions can be used to globally handle errors that occur during the entitlement fetching process initiated by the provider.
  • Hook Level: Each hook (useAllEntitlements, useBooleanEntitlement, etc.) returns an AsyncState object which includes an error: Error | null property. You can check this to handle errors specific to that data slice.
  • Context Level: useParityDeals() also returns a global error: Error | null state, reflecting errors from the provider’s most recent fetch operation.

9. Example Usage

A comprehensive example is provided within the comments of the SDK code, demonstrating provider setup and component usage. The core setup involves:

  1. Wrapping your application with ParityDealsProvider and providing the required props (customerId, accessToken)
  2. Using hooks like useBooleanEntitlement or conditional components like ShowWhenBooleanEntitled in your components to control UI and behavior based on entitlements.

10. API Request Service

The SDK relies on an apiRequest function for making HTTP requests. The SDK’s ParityDealsProvider passes configuration like timeout, maxRetries, backoffBaseDelay, and accessToken to this function.

  • Your Responsibility: You need to ensure that your project includes an implementation of this apiRequest service (e.g., in src/services/makeRequest.service.ts) that matches the ApiRequestConfig and ApiResponse interfaces used by the SDK. This service should handle actual HTTP communication, including appending query parameters passed via ApiRequestConfig.queryParams and using the accessToken to set the Authorization header.
  • The placeholder apiRequest function included in the SDK’s source code is for demonstration and type-checking purposes only and will not make real API calls.

11. Project Structure (for contributors/reference)

The SDK source code (src/) is organized as follows:

  • components/: Contains conditional rendering React components.
    • ShowWhenBooleanEntitled.tsx
    • ShowWhenConfigEntitled.tsx
    • ShowWhenMeteredEntitled.tsx
    • ShowWhenEntitledInternal.tsx (Internal helper, not typically exported)
    • index.ts (Exports public components)
  • context/: Defines the React Context.
    • ParityDealsContext.ts
  • hooks/: Contains all custom React Hooks.
    • useParityDeals.ts
    • useAllEntitlements.ts
    • useBooleanEntitlement.ts
    • useConfigEntitlement.ts
    • useMeteredEntitlement.ts
    • index.ts (Exports all hooks)
  • provider/: Contains the main ParityDealsProvider.
    • ParityDealsProvider.tsx
  • types/: Contains all TypeScript definitions.
    • api.types.ts (Raw types from API)
    • sdk.types.ts (Processed types for SDK and public use)
    • index.ts (Re-exports all types)
  • utils/: Contains utility functions.
    • transformations.ts (For transformApiEntitlements)
    • index.ts (Exports utilities)
  • index.ts: The main entry point of the SDK, re-exporting all public APIs (provider, hooks, components, types).

This documentation should provide a good starting point for developers using your @paritydeals/react-sdk. Remember to replace placeholder URLs and token examples with relevant information for your users.