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

@actschurch/ccms-sdk

v0.0.4

Published

CCMS TypeScript SDK for Web APIs and WebSockets (Express, Web, React Native)

Readme

CCMS SDK

Official TypeScript/JavaScript SDK for the CCMS (Church/Community Management System) Platform. This SDK provides a comprehensive set of tools for building web and mobile applications that integrate with the CCMS backend.

Features

  • Cross-Platform: Works seamlessly on Web (React, Vue, vanilla JS) and React Native
  • TypeScript First: Full type definitions for all APIs and models
  • Authentication: Complete auth flow with automatic token refresh
  • Real-time Communication: SignalR-based presence tracking and log streaming with automatic reconnection
  • Permission Management: Role-based access control with feature definitions
  • React Integration: 50+ hooks and components for React applications
  • Comprehensive Services: 15+ domain-specific service modules with 100+ API endpoints
  • Utility Library: Extensive utilities for strings, dates, arrays, validation, and more
  • Developer Experience: Auto-complete, type safety, and comprehensive documentation

What's New

Latest Updates

  • 🚀 Enhanced Service Architecture: Comprehensive service modules covering 18 domains with 168+ services including Task Management (12 services), Communication (6 services), Procurement (18 services), Payments (14 services), Projects (17 services), HR (19 services), Meetings (14 services), and more. See Services for details.
  • 📡 New Realtime Module: Completely redesigned real-time communication with SignalR-based hubs for presence tracking (with activity detection) and log streaming (application, API, query, and dashboard logs). See Real-time for migration guide.
  • ⚛️ Expanded React Hooks: 18 service-specific hooks (useTaskServices, useCommunicationServices, useMeetingsServices, etc.) and 8 dedicated realtime hooks for presence tracking and log streaming.
  • 🎨 Activity Detection: Automatic user status updates based on activity for both web (mouse, keyboard, visibility) and React Native (AppState) platforms.
  • 📚 Comprehensive Documentation: Detailed module-level documentation for Services and Realtime.

Table of Contents


Installation

npm install @actschurch/ccms-sdk
# or
yarn add @actschurch/ccms-sdk
# or
pnpm add @actschurch/ccms-sdk

Peer Dependencies

For React applications:

npm install react@^18.0.0

Quick Start

Basic Setup (Vanilla JavaScript/TypeScript)

import { HttpClient, AuthManager, LocalStorageAdapter } from '@actschurch/ccms-sdk';

// Create HTTP client
const http = new HttpClient({
  baseUrl: 'https://api.yourccms.com',
});

// Create auth manager with storage
const authManager = new AuthManager(http, {
  storage: new LocalStorageAdapter(),
  autoRefresh: true,
});

// Initialize auth (loads user from storage)
await authManager.initialize();

// Login
const user = await authManager.login({
  email: '[email protected]',
  password: 'password123',
});

// Make authenticated requests
const response = await http.get('/api/members');

React Setup

import { CCMSProvider, useCCMS, useAuth } from '@actschurch/ccms-sdk';

// Wrap your app with CCMSProvider
function App() {
  return (
    <CCMSProvider
      config={{
        baseUrl: 'https://api.yourccms.com',
        enableRealtime: true,
      }}
    >
      <MyApp />
    </CCMSProvider>
  );
}

// Use hooks in your components
function Dashboard() {
  const { http } = useCCMS();
  const { user, isAuthenticated, login, logout } = useAuth();

  if (!isAuthenticated) {
    return <LoginForm onLogin={login} />;
  }

  return (
    <div>
      <h1>Welcome, {user?.firstName}!</h1>
      <button onClick={logout}>Logout</button>
    </div>
  );
}

Core Concepts

HTTP Client

The HttpClient is the foundation for all API communication. It handles request/response interceptors, authentication headers, and error handling.

import { HttpClient } from '@actschurch/ccms-sdk';

const http = new HttpClient({
  baseUrl: 'https://api.yourccms.com',
  timeout: 30000, // 30 seconds
  headers: {
    'X-Custom-Header': 'value',
  },
});

// GET request
const members = await http.get<Member[]>('/api/members');

// POST request
const newMember = await http.post<Member>('/api/members', {
  firstName: 'John',
  lastName: 'Doe',
  email: '[email protected]',
});

// PUT request
const updated = await http.put<Member>('/api/members/123', {
  firstName: 'Jane',
});

// DELETE request
await http.delete('/api/members/123');

// Request with query parameters
const filtered = await http.get<Member[]>('/api/members', {
  params: { status: 'active', page: 1, pageSize: 20 },
});

Interceptors

Add request/response interceptors for logging, error handling, or modifying requests:

// Request interceptor
http.interceptors.request.use(
  (config) => {
    console.log('Request:', config.url);
    return config;
  },
  (error) => Promise.reject(error)
);

// Response interceptor
http.interceptors.response.use(
  (response) => {
    console.log('Response:', response.status);
    return response;
  },
  (error) => {
    if (error.status === 401) {
      // Handle unauthorized
    }
    return Promise.reject(error);
  }
);

Authentication

The AuthManager handles the complete authentication flow including login, logout, token refresh, and session persistence.

import { AuthManager, LocalStorageAdapter, MemoryStorageAdapter } from '@actschurch/ccms-sdk';

// Create auth manager
const authManager = new AuthManager(http, {
  // Storage adapter (choose based on platform)
  storage: new LocalStorageAdapter(), // Web
  // storage: new AsyncStorageAdapter(AsyncStorage), // React Native
  // storage: new MemoryStorageAdapter(), // SSR or testing

  // Token refresh configuration
  autoRefresh: true,
  refreshThresholdSeconds: 60, // Refresh 60s before expiry
  refreshCheckIntervalMs: 30000, // Check every 30s

  // Callbacks
  onLogin: (user) => console.log('User logged in:', user.email),
  onLogout: () => console.log('User logged out'),
  onRefresh: (user) => console.log('Token refreshed'),
  onError: (error) => console.error('Auth error:', error),
});

// Initialize (loads persisted session)
const user = await authManager.initialize();

// Login
try {
  const user = await authManager.login({
    email: '[email protected]',
    password: 'password123',
  });
  console.log('Logged in as:', user.firstName);
} catch (error) {
  console.error('Login failed:', error.message);
}

// Get current state
const state = authManager.getState();
// { isAuthenticated: true, user: {...}, isLoading: false, error: null }

// Check permissions
if (authManager.hasRole('admin')) {
  // User is admin
}

if (authManager.hasRight('members.edit')) {
  // User can edit members
}

// Subscribe to state changes
const unsubscribe = authManager.subscribe((state) => {
  console.log('Auth state changed:', state);
});

// Logout
await authManager.logout();

// Cleanup
unsubscribe();
authManager.destroy();

Storage Adapters

Different storage adapters for different platforms:

import {
  LocalStorageAdapter,      // Web - localStorage
  SessionStorageAdapter,    // Web - sessionStorage
  MemoryStorageAdapter,     // In-memory (SSR/testing)
  AsyncStorageAdapter,      // React Native
  SecureStorageAdapter,     // React Native - secure storage
  CookieStorageAdapter,     // SSR/universal apps
  GenericStorageAuthAdapter, // Custom storage
} from '@actschurch/ccms-sdk';

// React Native with AsyncStorage
import AsyncStorage from '@react-native-async-storage/async-storage';
const storage = new AsyncStorageAdapter(AsyncStorage);

// React Native with Expo SecureStore
import * as SecureStore from 'expo-secure-store';
const storage = new SecureStorageAdapter(SecureStore);

// Custom storage key
const storage = new LocalStorageAdapter('my_app_auth');

Permissions

The PermissionManager handles feature-based access control using roles and permissions.

import { PermissionManager, defineFeature, requires } from '@actschurch/ccms-sdk';

// Create permission manager
const permissions = new PermissionManager({
  defaultAllow: false,
  debug: true,
});

// Define features with requirements
permissions.registerFeatures([
  defineFeature('members.view', 'View Members', [
    requires.anyRole(['admin', 'staff', 'member']),
  ]),

  defineFeature('members.edit', 'Edit Members', [
    requires.anyRole(['admin', 'staff']),
    requires.right('members.write'),
  ]),

  defineFeature('admin.dashboard', 'Admin Dashboard', [
    requires.role('admin'),
  ]),

  defineFeature('reports.financial', 'Financial Reports', [
    requires.allRoles(['admin', 'finance']),
  ]),

  defineFeature('custom.feature', 'Custom Feature', [
    requires.custom(() => someCondition(), 'customCheck'),
  ]),
]);

// Set user context (usually done after login)
permissions.setContext({
  roles: user.roles,
  rights: user.rights,
  isAuthenticated: true,
  userId: user.id,
});

// Check permissions
if (permissions.can('members.edit')) {
  // User can edit members
}

// Get detailed check result
const result = permissions.check('members.edit');
// { allowed: false, reason: '...', missing: ['members.write'] }

// Direct role/right checks
permissions.hasRole('admin');
permissions.hasAnyRole(['admin', 'staff']);
permissions.hasAllRoles(['admin', 'finance']);
permissions.hasRight('members.write');
permissions.hasAnyRight(['members.read', 'members.write']);

// Listen for denied access attempts
permissions.onDenied((event) => {
  console.log('Access denied to feature:', event.featureId);
  analytics.track('permission_denied', event);
});

Real-time

The CCMS SDK provides robust real-time communication infrastructure using SignalR WebSockets with automatic reconnection, type-safe event handling, and React integration.

Key Features

  • 🔄 Automatic Reconnection - Exponential backoff strategy with delays: [2s, 4s, 8s, 16s, 30s]
  • 🔐 JWT Authentication - Seamless integration with CCMS auth system
  • 📡 Multiple Hubs - Separate hubs for presence tracking (1 hub) and log streaming (4 hubs)
  • ⚛️ React Integration - First-class React support with 8 dedicated hooks and context providers
  • 📱 Cross-Platform - Works in web browsers and React Native applications
  • 🎨 Activity Detection - Automatic user status updates based on platform-specific activity monitoring
  • 🔌 Auto-Management - Automatic connection on login, disconnection on logout

For comprehensive documentation, see the Realtime Module Documentation.

Presence Tracking

Track user presence and status across the platform with automatic activity detection and real-time updates.

Features:

  • Auto-Connect on Login - PresenceProvider automatically connects when user authenticates
  • Activity Detection - Monitors user activity (web: mouse/keyboard/visibility; React Native: AppState)
  • Auto-Away Status - Automatically sets status to "Away" after 5 minutes of inactivity
  • Multi-Device Support - Handles multiple concurrent connections per user
  • Status Broadcasting - Real-time updates broadcast to all connected clients

Available Statuses: Online, Away, Busy, Offline

import { PresenceProvider, usePresence, useUserPresence, useOnlineUsers, usePresenceStatus, PresenceStatus } from '@actschurch/ccms-sdk/realtime/presence';

// Setup in your app root with auto-connection management
function App() {
  return (
    <PresenceProvider
      authManager={authManager}
      baseUrl="https://api.example.com"
      options={{
        activityTimeout: 5 * 60 * 1000,        // 5 minutes until "Away"
        enableActivityDetection: true,
        platform: 'web',                       // or 'react-native'
        autoReconnect: true,
        maxReconnectAttempts: 10,
      }}
      onConnectionChange={(connected) => console.log('Presence:', connected)}
    >
      <YourApp />
    </PresenceProvider>
  );
}

// Use in components - get specific user's presence
function UserStatus({ userId }: { userId: string }) {
  const userPresence = useUserPresence(userId);
  const { updateStatus } = usePresence();

  return (
    <div className="flex items-center gap-2">
      <StatusIndicator status={userPresence?.status || 'Offline'} />
      <span>{userPresence?.statusMessage || userPresence?.status}</span>
      <button onClick={() => updateStatus(PresenceStatus.Busy, 'In a meeting')}>
        Set Busy
      </button>
    </div>
  );
}

// Show all online users
function OnlineUsersList() {
  const onlineUsers = useOnlineUsers(); // Returns UserPresenceUpdate[]
  const myStatus = usePresenceStatus();

  return (
    <div>
      <p>My Status: {myStatus}</p>
      <p>Online Users: {onlineUsers.length}</p>
      <ul>
        {onlineUsers.map(user => (
          <li key={user.userId}>{user.userName} - {user.status}</li>
        ))}
      </ul>
    </div>
  );
}

Activity Detection:

  • Web Platform: Monitors mouse movement, clicks, keyboard, scrolling, tab visibility
  • React Native: Monitors AppState changes (foreground/background)
  • Throttled: Maximum 1 status update per second for performance
  • Configurable: Customize inactivity timeout and check intervals

Real-time Log Streaming

Stream application logs, API requests, database queries, and system metrics in real-time with powerful filtering capabilities.

Available Log Hubs:

  1. Application Logs - General application logs (errors, warnings, information)
  2. API Logs - HTTP request/response logs with performance metrics
  3. Query Logs - Database query performance and slow query tracking
  4. Dashboard - Aggregated statistics and system health metrics

Features:

  • Filter-Based Subscription - Subscribe only to relevant logs (by service, level, duration, etc.)
  • Buffer Management - Configurable in-memory buffer with FIFO eviction
  • Auto-Load Recent - Optionally load historical logs on subscription
  • Correlation Tracing - Track all logs related to a single request by correlation ID
  • Manual Connection - Connect/disconnect explicitly or with auto-connect option
import {
  useApplicationLogs,
  useApiLogs,
  useQueryLogs,
  useDashboard,
} from '@actschurch/ccms-sdk/realtime/logs';

// Application logs with filtering and event handling
function LogsViewer() {
  const {
    logs,
    isConnected,
    isSubscribed,
    error,
    connect,
    disconnect,
    subscribe,
    unsubscribe,
    clearLogs,
    loadRecent,
  } = useApplicationLogs({
    autoConnect: true,
    filter: {
      serviceNames: ['CCMS.API', 'CCMS.Tasks'],
      logLevels: ['Error', 'Warning', 'Critical'],
      userId: currentUser?.id,                        // Filter by user
    },
    maxBufferSize: 1000,                              // Keep last 1000 logs
    autoLoadRecent: true,                             // Load recent on subscribe
    recentLogsLimit: 100,                             // Load 100 recent logs
    onLog: (log) => {
      // Handle new log in real-time
      if (log.level === 'Critical') {
        showNotification({ title: 'Critical Error', message: log.message });
      }
    },
  });

  useEffect(() => {
    subscribe();
    return () => disconnect();
  }, []);

  return (
    <div>
      <div className="status">
        Status: {isConnected ? '🟢 Connected' : '🔴 Disconnected'}
        {isSubscribed && ' (Subscribed)'}
      </div>
      <button onClick={clearLogs}>Clear Logs</button>
      <table>
        <thead>
          <tr>
            <th>Time</th>
            <th>Level</th>
            <th>Service</th>
            <th>Message</th>
          </tr>
        </thead>
        <tbody>
          {logs.map((log) => (
            <tr key={log.id} className={`log-${log.level.toLowerCase()}`}>
              <td>{new Date(log.timestamp).toLocaleString()}</td>
              <td>{log.level}</td>
              <td>{log.serviceName}</td>
              <td>{log.message}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// API request logs - track slow or failed requests
function ApiLogsMonitor() {
  const { logs } = useApiLogs({
    autoConnect: true,
    filter: {
      minDurationMs: 1000,                             // Only slow requests (>1s)
      statusCodes: [400, 404, 500, 502, 503],          // Error codes
      pathFilter: '/api/',                             // Path pattern
    },
  });

  return (
    <div>
      <h3>Slow & Failed API Requests</h3>
      {logs.map(log => (
        <div key={log.id}>
          <span>{log.httpMethod} {log.path}</span>
          <span>Status: {log.statusCode}</span>
          <span>Duration: {log.durationMs}ms</span>
        </div>
      ))}
    </div>
  );
}

// Query performance logs - track slow database queries
function QueryPerformanceMonitor() {
  const { logs } = useQueryLogs({
    filter: {
      slowOnly: true,                                  // Only marked as slow
      minDurationMs: 500,                              // >500ms
      queryTypes: ['SELECT'],                          // Only SELECT queries
    },
  });

  return (
    <div>
      <h3>Slow Database Queries</h3>
      {logs.map(log => (
        <div key={log.id}>
          <span>{log.queryType} - {log.entityType}</span>
          <span>Duration: {log.durationMs}ms</span>
          <span>Rows: {log.rowCount}</span>
        </div>
      ))}
    </div>
  );
}

// System dashboard with real-time statistics
function PerformanceDashboard() {
  const {
    stats,
    isConnected,
    refreshStats,
    getLogsByCorrelationId,
    getRecentErrors,
    startAutoRefresh,
    stopAutoRefresh,
  } = useDashboard({
    autoConnect: true,
    refreshInterval: 5000,                             // Auto-refresh every 5s
    onUpdate: (stats) => {
      console.log('Dashboard updated:', stats);
    },
  });

  useEffect(() => {
    startAutoRefresh();
    return () => stopAutoRefresh();
  }, []);

  const handleCorrelationTrace = async (correlationId: string) => {
    const trace = await getLogsByCorrelationId(correlationId);
    // trace.applicationLogs, trace.apiLogs, trace.queryLogs
    console.log('Full request trace:', trace);
  };

  return (
    <div>
      <h2>System Health Dashboard</h2>
      <div className="grid grid-cols-3 gap-4">
        <MetricCard
          title="Avg Response Time"
          value={`${stats?.averageResponseTime.toFixed(2)}ms`}
        />
        <MetricCard
          title="Error Rate"
          value={`${((stats?.errorRequests / stats?.totalApiRequests) * 100).toFixed(2)}%`}
          alert={stats?.errorRequests > 10}
        />
        <MetricCard
          title="Slow Queries"
          value={stats?.slowQueries}
        />
        <MetricCard
          title="Active Services"
          value={stats?.activeServices.length}
        />
        <MetricCard
          title="Logs/Minute"
          value={stats?.logsPerMinute}
        />
        <MetricCard
          title="Total Errors"
          value={stats?.errorCount}
        />
      </div>
      <button onClick={refreshStats}>Refresh Now</button>
    </div>
  );
}

Log Entry Structures:

  • ApplicationLogEntry: timestamp, level, category, message, exception, correlationId, serviceName, properties
  • ApiRequestLogEntry: httpMethod, path, statusCode, durationMs, requestBody, responseBody, headers
  • QueryPerformanceLogEntry: queryType, entityType, queryText, durationMs, rowCount, isSlowQuery
  • DashboardStats: Aggregated metrics including averages, counts, and active services

Migration from Legacy RealtimeClient

The old RealtimeClient is deprecated. Migrate to the new SignalR-based modules:

// Old (deprecated)
import { RealtimeClient } from '@actschurch/ccms-sdk';
const realtime = new RealtimeClient(config);
realtime.updatePresence('Online');

// New (recommended)
import { usePresence } from '@actschurch/ccms-sdk/realtime/presence';
const { updateStatus } = usePresence();
updateStatus(PresenceStatus.Online);

Error Handling

The SDK provides comprehensive error handling utilities.

import { ErrorHandler, CCMSError } from '@actschurch/ccms-sdk';

// Create error handler
const errorHandler = new ErrorHandler({
  onError: (error) => {
    // Global error handling
    console.error('Error:', error.message);
  },
  displayMode: 'toast', // 'toast' | 'modal' | 'none'
});

// Handle errors
try {
  await someOperation();
} catch (error) {
  errorHandler.handle(error);
}

// Custom error class
throw new CCMSError('Something went wrong', {
  code: 'VALIDATION_ERROR',
  statusCode: 400,
  details: { field: 'email' },
});

React Integration

Provider Setup

Wrap your application with CCMSProvider:

import { CCMSProvider } from '@actschurch/ccms-sdk';

function App() {
  return (
    <CCMSProvider
      config={{
        baseUrl: 'https://api.yourccms.com',
        enableRealtime: true,
        realtimeUrl: 'wss://api.yourccms.com', // Optional
      }}
      authConfig={{
        autoRefresh: true,
        refreshThresholdSeconds: 60,
      }}
    >
      <YourApp />
    </CCMSProvider>
  );
}

Hooks

Core Hooks

import {
  useCCMS,
  useAuth,
  useHttpClient,
  useRealtime,
  usePermissions,
} from '@actschurch/ccms-sdk';

function MyComponent() {
  // Access full SDK context
  const { http, auth, realtime, permissions } = useCCMS();

  // Or use specific hooks
  const httpClient = useHttpClient();
  const realtimeClient = useRealtime();
  const permissionManager = usePermissions();
}

Authentication Hooks

import { useAuth, useIsAuthenticated, useUser, useHasRole, useHasRight } from '@actschurch/ccms-sdk';

function Profile() {
  const { user, isAuthenticated, isLoading, login, logout } = useAuth();

  // Or use individual hooks
  const isLoggedIn = useIsAuthenticated();
  const currentUser = useUser();
  const isAdmin = useHasRole('admin');
  const canEditMembers = useHasRight('members.edit');

  if (isLoading) return <Loading />;
  if (!isAuthenticated) return <LoginForm />;

  return (
    <div>
      <h1>Welcome, {user?.firstName}</h1>
      {isAdmin && <AdminPanel />}
      {canEditMembers && <EditButton />}
    </div>
  );
}

API Hooks

import { useQuery, useMutation, useInfiniteQuery, usePrefetch } from '@actschurch/ccms-sdk';

function MemberList() {
  // Fetch data
  const {
    data: members,
    isLoading,
    error,
    refetch,
  } = useQuery<Member[]>('/api/members', {
    enabled: true,
    refetchOnFocus: true,
  });

  // Mutations
  const { mutate: createMember, isLoading: isCreating } = useMutation<Member>(
    '/api/members',
    'POST',
    {
      onSuccess: (member) => {
        console.log('Created:', member);
        refetch();
      },
      onError: (error) => console.error(error),
    }
  );

  // Infinite scrolling
  const {
    pages,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery<Member>('/api/members', undefined, {
    pageSize: 20,
  });

  // Prefetch for navigation
  const { prefetch } = usePrefetch();

  const handleHover = (memberId: string) => {
    prefetch<Member>(`/api/members/${memberId}`);
  };
}

Realtime Hooks

Presence Hooks
import {
  usePresence,
  usePresenceStatus,
  useOnlineUsers,
  useUserPresence,
} from '@actschurch/ccms-sdk/realtime/presence';

function ChatRoom() {
  // Main presence hook
  const { state, updateStatus, getUserPresence, getAllPresence } = usePresence();

  // Get current user's status
  const myStatus = usePresenceStatus(); // 'Online' | 'Away' | 'Busy' | 'Offline'

  // Get all online users
  const onlineUsers = useOnlineUsers(); // UserPresenceUpdate[]

  // Get specific user's presence
  const userPresence = useUserPresence('user-123');

  useEffect(() => {
    updateStatus('Online', 'In chat room');
    return () => updateStatus('Offline');
  }, []);

  return (
    <div>
      <p>Your status: {myStatus}</p>
      <p>Online users: {onlineUsers.length}</p>
      {userPresence && <span>{userPresence.status}</span>}
    </div>
  );
}
Log Streaming Hooks
import {
  useApplicationLogs,
  useApiLogs,
  useQueryLogs,
  useDashboard,
} from '@actschurch/ccms-sdk/realtime/logs';

function LogMonitor() {
  // Application logs
  const {
    logs: appLogs,
    isConnected,
    subscribe,
    clearLogs,
    loadRecent,
  } = useApplicationLogs({
    autoConnect: true,
    filter: { logLevels: ['Error', 'Critical'] },
    maxBufferSize: 1000,
  });

  // API request logs
  const { logs: apiLogs } = useApiLogs({
    filter: { minDurationMs: 1000 }, // Slow requests only
  });

  // Database query logs
  const { logs: queryLogs } = useQueryLogs({
    filter: { slowOnly: true },
  });

  // Dashboard statistics
  const { stats, refreshStats, getLogsByCorrelationId } = useDashboard({
    autoConnect: true,
    refreshInterval: 5000,
  });

  return (/* ... */);
}
Legacy Realtime Hooks (Deprecated)
// ⚠️ DEPRECATED: These hooks are deprecated and will be removed in v2.0.0
// Use the new hooks above instead

import { useRealtimeEvent, useConnectionState } from '@actschurch/ccms-sdk';

function OldComponent() {
  const connectionState = useConnectionState(); // Use usePresence() instead
  useRealtimeEvent('event', handler); // Use specific hooks instead
}

Utility Hooks

import {
  useDebounce,
  useThrottle,
  usePrevious,
  useStorage,
  useNetworkStatus,
  useToggle,
  useCounter,
  useArray,
  useMap,
  useInterval,
  useTimeout,
  useMediaQuery,
  useClipboard,
  useClickOutside,
  useKeyPress,
} from '@actschurch/ccms-sdk';

function SearchComponent() {
  const [search, setSearch] = useState('');
  const debouncedSearch = useDebounce(search, 300);

  // Network status
  const { isOnline, wasOffline } = useNetworkStatus();

  // Persistent storage (cross-platform)
  const [theme, setTheme] = useStorage('theme', 'light');

  // Boolean toggle
  const [isOpen, toggle] = useToggle(false);

  // Counter with limits
  const { count, increment, decrement } = useCounter(0, { min: 0, max: 100 });

  // Array operations
  const { array, push, remove, clear } = useArray<string>([]);

  // Media queries
  const isMobile = useMediaQuery('(max-width: 768px)');

  // Clipboard
  const { copy, copied } = useClipboard();

  // Click outside detection
  const ref = useClickOutside<HTMLDivElement>(() => setIsOpen(false));

  // Keyboard shortcuts
  useKeyPress('k', () => openSearch(), { meta: true }); // Cmd+K
}

Components

Permission Components

import { Can, RequireAuth, RequireRole, RequireRight } from '@actschurch/ccms-sdk';

function App() {
  return (
    <RequireAuth fallback={<LoginPage />}>
      <Dashboard />
    </RequireAuth>
  );
}

function Dashboard() {
  return (
    <div>
      {/* Feature-based access */}
      <Can feature="members.view">
        <MemberList />
      </Can>

      {/* Role-based access */}
      <RequireRole role="admin" fallback={<AccessDenied />}>
        <AdminPanel />
      </RequireRole>

      {/* Multiple roles (any) */}
      <RequireRole roles={['admin', 'staff']} requireAll={false}>
        <StaffTools />
      </RequireRole>

      {/* Right-based access */}
      <RequireRight right="reports.view">
        <Reports />
      </RequireRight>
    </div>
  );
}

Error Boundary

import { ErrorBoundary } from '@actschurch/ccms-sdk';

function App() {
  return (
    <ErrorBoundary
      fallback={({ error, reset }) => (
        <div>
          <h1>Something went wrong</h1>
          <p>{error.message}</p>
          <button onClick={reset}>Try Again</button>
        </div>
      )}
    >
      <MyApp />
    </ErrorBoundary>
  );
}

React Native Setup

Configure Global Storage

// In your app entry point (App.tsx or index.js)
import AsyncStorage from '@react-native-async-storage/async-storage';
import NetInfo from '@react-native-community/netinfo';
import { setGlobalStorage, setGlobalNetworkStatus } from '@actschurch/ccms-sdk';

// Configure storage (do this before using any SDK features)
setGlobalStorage(AsyncStorage);

// Configure network status detection
setGlobalNetworkStatus({
  isOnline: async () => {
    const state = await NetInfo.fetch();
    return state.isConnected ?? false;
  },
  subscribe: (callback) => {
    return NetInfo.addEventListener((state) => {
      callback(state.isConnected ?? false);
    });
  },
});

Use with Expo SecureStore

import * as SecureStore from 'expo-secure-store';
import { SecureStorageAdapter, AuthManager } from '@actschurch/ccms-sdk';

const authManager = new AuthManager(http, {
  storage: new SecureStorageAdapter(SecureStore),
});

Services

The SDK provides pre-built service classes that encapsulate common API operations for each domain. Services handle request formatting, response parsing, and provide a clean interface for interacting with the CCMS backend.

Available Service Modules

| Module | Services | Key Services | |--------|----------|--------------| | Task Management | 12 services | TaskService, TaskStatusService, TaskPriorityService, TaskProgressStageService, TaskAssignmentService, TaskAttachmentService, TaskCommentService, TaskNoteService, TaskLogService, LogTypeService, TaskNotificationService, TaskNotificationQueueService | | User Management | 9 services | UserService, RoleService, RightService, AuthService, AuditService, AdminService, SystemService, UserPreferencesService, UserPushDeviceService | | Payments | 14 services | PaymentTransactionService, PayerService, PaymentMethodService, TransactionStatusService, TransactionCategoryService, TransactionRefundService, RefundStatusService, BillingAgreementService, RecurringTransactionService, SettlementService, SettlementLineService, PaymentIpnEventService, PaymentNotificationQueueService, PayFastWebhookService | | Procurement | 18 services | PurchaseRequestService, QuotationService, InvoiceService, RequestAttachmentService, RequestCommentService, RequestTypeService, RequestStatusService, RequestStageService, QuotationStatusService, InvoiceStatusService, ProcurementRoleTypeService, NotificationService, AuditLogService, QuotationLineService, InvoiceLineService, RequestApprovalStatusService, SagePurchaseOrderService, SageItemService | | Projects | 17 services | ProjectService, ProjectStatusService, ProjectTypeService, ProjectAuditLogService, ProjectMessageService, ProjectMilestoneService, ProjectMilestoneTaskService, ProjectRiskService, ProjectTeamMemberService, TaskTimeLogService, ProjectResourceService, ProjectDocumentService, PlannedBudgetItemService, TaskDependencyService, ResourceTypeService, ProjectRoleService, BudgetLineItemService | | Orders | 6 services | OrderService, OrderLineService, OrderPaymentService, OrderStatusService, PaymentStatusService, OrderNotificationService | | Meetings | 14 services | MeetingService, MeetingStatusService, MeetingTypeService, MeetingVenueService, MeetingAttendeeService, MeetingAttendanceStatusService, MeetingSetupService, MeetingRequestService, MeetingCommentService, MeetingFileService, SetupInMeetingService, RequestInMeetingService, LocationVenueRequestService, LocationVenueSetupService | | Members | 9 services | MemberService, FamilyService, MemberTypeService, MaritalStatusService, MemberAddressService, MemberLocationService, AllergyService, DisabilityService, RelationshipService | | HR | 19 services | EmployeeService, LeaveService, DutyService, EmployeeDutyService, EmployeeFileCategoryService, EmployeeFileTypeService, EmployeeFileService, EmployeeStatusService, EmployeeTypeService, LeaveDocumentTypeService, LeaveDocumentService, LeaveDutyService, LeaveNotificationQueueService, LeaveStatusService, LeaveTypeService, PolicyService, PolicyCategoryService, PolicySignatureService | | Departments | 10 services | DepartmentService, DesignationService, DesignationTaskService, MemberDesignationService, MemberInDepartmentService, MinistryService, MinistryActivityService, MinistryEquipmentService, MinistryRoleService, MinistryTeamService | | Communication | 6 services | EmailService, SmsService, PushNotificationService, WhatsAppService, TemplateService, DeviceService | | File Management | 2 services | FileService, MultipartUploadService | | Locations | 8 services | LocationService, AddressService, LocationInfoService, LocationLeaderService, LocationSocialMediaService, LocationVenueService, ServiceTimeService, SocialMediaService | | Products | 8 services | ProductService, ProductTypeService, ProductColorService, ProductSizeService, ProductImageService, ProductStockService, ProductTransactionService, TransactionTypeService | | Suppliers | 4 services | SupplierService, SupplierCategoryService, SupplierContactService, SupplierNoteService | | Resources | 8 services | CourseService, CourseCategoryService, CourseSessionService, UsageLogService, CourseStatusService, CourseCategoryStatusService, CourseSessionStatusService, CourseSessionTypeService | | Feedback | 5 services | FeedbackService, FeedbackCategoryService, FeedbackTypeService, FeedbackCategoryRecipientService, FeedbackNotificationQueueService | | System | 10 services | SystemService, ApiRequestLogService, QueryPerformanceLogService, LogsService, HealthService, ServicesService, RabbitMQManagementService, RedisManagementService, RabbitMQTestService, RedisTestService | | Generators | 4 services | BarcodeService, QrCodeService, UtilityCodeService, GeneratedCodeService |

For detailed information about the service architecture and how to create custom services, see Services Module Documentation.

Using Services

import { MemberService, TaskService } from '@actschurch/ccms-sdk';

// Initialize services with HTTP client
const memberService = new MemberService(http);
const taskService = new TaskService(http);

// Member operations
const members = await memberService.getAll({ page: 1, pageSize: 20 });
const member = await memberService.getById('member-123');
const newMember = await memberService.create({
  firstName: 'John',
  lastName: 'Doe',
  email: '[email protected]',
});
await memberService.update('member-123', { phone: '+1234567890' });
await memberService.delete('member-123');

// Search members
const searchResults = await memberService.search({
  query: 'John',
  filters: { status: 'active', memberType: 'regular' },
  sort: { field: 'lastName', direction: 'asc' },
});

// Task operations
const tasks = await taskService.getMyTasks();
const task = await taskService.create({
  title: 'Follow up with new member',
  description: 'Welcome call and orientation',
  assignedTo: ['user-456'],
  dueDate: '2024-02-01',
  priority: 'high',
});
await taskService.updateStatus('task-789', 'completed');
await taskService.addComment('task-789', 'Completed the follow-up call');

Service with React Hooks

The SDK provides dedicated hooks for each service module for seamless React integration:

import {
  useTaskServices,
  useUsersServices,
  useMembersServices,
  useMeetingsServices,
  useLocationsServices,
  useFileServices,
  useCommunicationServices,
  useSupplierServices,
  useResourcesServices,
  useProjectsServices,
  useProcurementsServices,
  useProductsServices,
  usePaymentServices,
  useOrderServices,
  useHrServices,
  useDepartmentsServices,
  useFeedbackServices,
  useSystemServices,
  useGeneratorsServices,
} from '@actschurch/ccms-sdk';

function TaskList() {
  const { task, taskStatus, taskPriority } = useTaskServices();
  const [tasks, setTasks] = useState<Task[]>([]);

  useEffect(() => {
    task.getAll().then(setTasks);
  }, []);

  const handleCreate = async (data: CreateTaskRequest) => {
    const newTask = await task.create(data);
    setTasks(prev => [...prev, newTask]);
  };

  return (/* ... */);
}

// Access multiple services in one module
function CommunicationDashboard() {
  const { email, sms, pushNotification, whatsApp } = useCommunicationServices();

  const sendMultiChannelNotification = async (message: string, recipients: string[]) => {
    await Promise.all([
      email.send({ to: recipients, subject: 'Notification', body: message }),
      sms.send({ to: recipients, message }),
      pushNotification.send({ userIds: recipients, title: 'Alert', body: message }),
    ]);
  };

  return (/* ... */);
}

// Use meeting services
function MeetingScheduler() {
  const { meeting, meetingAttendee, meetingVenue } = useMeetingsServices();

  const createMeeting = async (data: MeetingRequest) => {
    const newMeeting = await meeting.create(data);
    await meetingAttendee.addAttendees(newMeeting.id, data.attendeeIds);
    return newMeeting;
  };

  return (/* ... */);
}

Custom Service Creation

You can create custom services by extending the base service class:

import { BaseService } from '@actschurch/ccms-sdk';

class CustomService extends BaseService {
  constructor(http: HttpClient) {
    super(http, '/api/custom');
  }

  async getCustomData(id: string): Promise<CustomData> {
    const response = await this.http.get<CustomData>(`${this.basePath}/${id}`);
    return response.data!;
  }

  async performCustomAction(data: ActionRequest): Promise<ActionResult> {
    const response = await this.http.post<ActionResult>(
      `${this.basePath}/action`,
      data
    );
    return response.data!;
  }
}

Service Configuration

Services can be configured with default options:

const memberService = new MemberService(http, {
  // Default pagination
  defaultPageSize: 50,

  // Cache configuration
  cacheEnabled: true,
  cacheTTL: 5 * 60 * 1000, // 5 minutes

  // Retry configuration
  retryOnError: true,
  maxRetries: 3,
});

Batch Operations

Services support batch operations for efficiency:

// Batch create
const members = await memberService.createMany([
  { firstName: 'John', lastName: 'Doe' },
  { firstName: 'Jane', lastName: 'Smith' },
]);

// Batch update
await memberService.updateMany([
  { id: 'member-1', status: 'active' },
  { id: 'member-2', status: 'active' },
]);

// Batch delete
await memberService.deleteMany(['member-3', 'member-4']);

Service Events

Services emit events for tracking operations:

memberService.on('created', (member) => {
  console.log('Member created:', member.id);
  analytics.track('member_created', { memberId: member.id });
});

memberService.on('updated', (member) => {
  console.log('Member updated:', member.id);
});

memberService.on('deleted', (id) => {
  console.log('Member deleted:', id);
});

memberService.on('error', (error, operation) => {
  console.error(`Error during ${operation}:`, error);
});

Utilities

The SDK includes comprehensive cross-platform utilities:

String Utilities

import {
  capitalize,
  toCamelCase,
  toKebabCase,
  toSnakeCase,
  toPascalCase,
  slugify,
  truncate,
  mask,
  getInitials,
  pluralize,
  similarity,
} from '@actschurch/ccms-sdk';

capitalize('hello world'); // "Hello world"
toCamelCase('hello-world'); // "helloWorld"
slugify('Hello World!'); // "hello-world"
truncate('Long text...', 10); // "Long te..."
mask('1234567890', 4); // "******7890"
getInitials('John Doe'); // "JD"
pluralize('item', 5); // "items"
similarity('hello', 'hallo'); // 0.8

Number Utilities

import {
  formatCurrency,
  formatNumber,
  formatPercentage,
  humanizeNumber,
  round,
  clamp,
  percentage,
  toOrdinal,
  formatFileSize,
  formatDurationFromSeconds,
} from '@actschurch/ccms-sdk';

formatCurrency(1234.56, 'USD'); // "$1,234.56"
formatNumber(1234567); // "1,234,567"
formatPercentage(0.456); // "45.60%"
humanizeNumber(1500000); // "1.5M"
round(3.14159, 2); // 3.14
clamp(150, 0, 100); // 100
toOrdinal(1); // "1st"
formatFileSize(1536); // "1.50 KB"
formatDurationFromSeconds(3661); // "1:01:01"

Date/Time Utilities

import {
  formatDate,
  parseDate,
  addDays,
  addMonths,
  differenceInDays,
  startOfDay,
  endOfDay,
  isWeekend,
  humanize,
  fromNow,
  toUnix,
  fromUnix,
} from '@actschurch/ccms-sdk';

formatDate(new Date(), 'YYYY-MM-DD'); // "2024-01-15"
addDays(new Date(), 7); // Date 7 days from now
differenceInDays(date1, date2); // Number of days between
humanize(pastDate); // "2 hours ago"
isWeekend(new Date()); // true/false

Array Utilities

import {
  unique,
  uniqueBy,
  chunk,
  sortBy,
  groupBy,
  partition,
  shuffle,
  sample,
  intersection,
  difference,
  union,
  flatten,
  moveItem,
} from '@actschurch/ccms-sdk';

unique([1, 2, 2, 3]); // [1, 2, 3]
uniqueBy(users, 'email'); // Remove duplicates by email
chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
sortBy(users, 'lastName', 'asc');
groupBy(users, 'department'); // { IT: [...], HR: [...] }
partition(numbers, n => n > 5); // [[6, 7, 8], [1, 2, 3]]
shuffle([1, 2, 3, 4, 5]); // Random order
sample(items, 3); // Random 3 items

Object Utilities

import {
  deepClone,
  deepMerge,
  get,
  set,
  pick,
  omit,
  flattenObject,
  unflattenObject,
  deepEqual,
  diff,
  isEmpty,
  mapValues,
  filterObject,
} from '@actschurch/ccms-sdk';

deepClone(complexObject);
deepMerge(defaults, userConfig);
get(obj, 'user.address.city', 'Unknown');
set(obj, 'user.address.city', 'New York');
pick(user, ['id', 'name', 'email']);
omit(user, ['password', 'secretKey']);
flattenObject({ a: { b: 1 } }); // { 'a.b': 1 }
deepEqual(obj1, obj2); // true/false
diff(original, modified); // { changed: 'fields' }

Validation Utilities

import {
  isEmail,
  isPhoneNumber,
  isUrl,
  isUUID,
  isStrongPassword,
  getPasswordStrength,
  isCreditCard,
  getCreditCardType,
  isIPv4,
  isIPv6,
  validateEmail,
  validatePassword,
  validateUsername,
  validateAll,
} from '@actschurch/ccms-sdk';

isEmail('[email protected]'); // true
isPhoneNumber('+1-555-123-4567'); // true
isStrongPassword('MyP@ss123!'); // true
getPasswordStrength('weak'); // { score: 1, level: 'weak', suggestions: [...] }
isCreditCard('4111111111111111'); // true (Luhn check)
getCreditCardType('4111...'); // 'visa'

// Detailed validation
validateEmail('invalid'); // { valid: false, error: 'Invalid email format' }
validatePassword('weak', { minLength: 8, requireSpecial: true });

// Multiple validations
validateAll([
  () => validateEmail(email),
  () => validatePassword(password),
  () => validateRequired(name, 'Name'),
]); // { valid: false, errors: ['...', '...'] }

Color Utilities

import {
  hexToRgb,
  rgbToHex,
  hexToHsl,
  lighten,
  darken,
  getContrastColor,
  isLightColor,
  mix,
  generatePalette,
} from '@actschurch/ccms-sdk';

hexToRgb('#ff5500'); // { r: 255, g: 85, b: 0 }
rgbToHex(255, 85, 0); // "#ff5500"
lighten('#ff5500', 0.2); // Lighter version
darken('#ff5500', 0.2); // Darker version
getContrastColor('#ff5500'); // '#ffffff' or '#000000'
mix('#ff0000', '#0000ff', 0.5); // Purple
generatePalette('#ff5500', 5); // { light: [...], dark: [...] }

Environment Utilities

import {
  getEnv,
  isProduction,
  isDevelopment,
  isBrowser,
  isReactNative,
  isNode,
  getPlatform,
  isMobile,
  isIOS,
  isAndroid,
  getBrowserInfo,
} from '@actschurch/ccms-sdk';

if (isProduction()) {
  // Production-only code
}

if (isReactNative()) {
  // React Native specific code
}

if (isMobile()) {
  // Mobile-specific UI
}

const platform = getPlatform(); // 'ios' | 'android' | 'web' | 'node' | 'unknown'

Device Utilities

import {
  getScreenInfo,
  getDeviceType,
  getOrientation,
  hasTouch,
  hasGeolocation,
  hasNotifications,
  prefersDarkMode,
  prefersReducedMotion,
  getPreferredLanguage,
  getTimezone,
  isOnline,
  getConnectionType,
  getCurrentBreakpoint,
  isAtLeast,
  isAtMost,
} from '@actschurch/ccms-sdk';

const screen = getScreenInfo(); // { width, height, pixelRatio, orientation }
const device = getDeviceType(); // 'phone' | 'tablet' | 'desktop'
const orientation = getOrientation(); // 'portrait' | 'landscape'

if (prefersDarkMode()) {
  // Apply dark theme
}

const breakpoint = getCurrentBreakpoint(); // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
if (isAtLeast('md')) {
  // Tablet and above
}

API Response Helpers

import {
  createSuccessResponse,
  createErrorResponse,
  createPaginatedResponse,
  isSuccessResponse,
  unwrapResponse,
  safeUnwrap,
  mapResponse,
  paginateArray,
  isSuccessStatus,
  getStatusMessage,
  fetchWithRetry,
  createQueryString,
  buildUrl,
} from '@actschurch/ccms-sdk';

// Create responses
const success = createSuccessResponse(data, 'Operation successful');
const error = createErrorResponse('Validation failed', ['Email is required']);
const paginated = createPaginatedResponse(items, { page: 1, pageSize: 20, totalItems: 100 });

// Check and unwrap
if (isSuccessResponse(response)) {
  const data = unwrapResponse(response);
}

// Safe unwrap with fallback
const users = safeUnwrap(response, []);

// Retry failed requests
const result = await fetchWithRetry(
  () => fetch('/api/data'),
  { maxRetries: 3, retryDelay: 1000, backoff: 'exponential' }
);

// Build URLs
const url = buildUrl('https://api.example.com', '/users', { page: 1, limit: 20 });
// "https://api.example.com/users?page=1&limit=20"

Error Utilities

import {
  safeTry,
  safeTryAsync,
  toErrorMessage,
  normalizeError,
  isNetworkError,
  isTimeoutError,
  isAbortError,
  retryOnError,
  createErrorBoundary,
  assert,
  assertDefined,
  formatErrorForUser,
  ValidationError,
  NetworkError,
  TimeoutError,
} from '@actschurch/ccms-sdk';

// Safe execution with fallback
const result = safeTry(() => JSON.parse(input), {});

// Async safe execution
const data = await safeTryAsync(() => fetchData(), defaultData);

// Error classification
if (isNetworkError(error)) {
  showOfflineMessage();
} else if (isTimeoutError(error)) {
  showTimeoutMessage();
}

// Retry with configuration
await retryOnError(fetchData, {
  maxRetries: 3,
  delayMs: 1000,
  shouldRetry: (error, attempt) => attempt < 3 && isNetworkError(error),
});

// Custom error classes
throw new ValidationError('Invalid input', { code: 'VALIDATION_ERROR' });

// User-friendly messages
const message = formatErrorForUser(error);
// "Unable to connect. Please check your internet connection."

Models

The SDK includes TypeScript models for all CCMS entities:

import {
  // Identity
  LoggedOnUser,
  UserModelView,
  RoleModelView,

  // Members
  Member,
  MemberModelView,
  MemberType,
  Family,

  // Tasks
  Task,
  TaskModelView,
  TaskStatus,
  TaskPriority,
  TaskAssignment,

  // Departments
  Department,
  Ministry,
  Designation,

  // Locations
  Location,
  Address,

  // And many more...
} from '@actschurch/ccms-sdk';

Testing

The SDK includes testing utilities for mocking:

import {
  MockHttpClient,
  MockAuthManager,
  MockRealtimeClient,
  MockPermissionManager,
  createMockUser,
  createMockPagedResult,
  TestProvider,
} from '@actschurch/ccms-sdk/testing';

// In your tests
describe('MyComponent', () => {
  it('renders member list', async () => {
    const mockHttp = new MockHttpClient();
    mockHttp.onGet('/api/members').reply(200, [
      { id: '1', firstName: 'John' },
      { id: '2', firstName: 'Jane' },
    ]);

    render(
      <TestProvider http={mockHttp}>
        <MemberList />
      </TestProvider>
    );

    await waitFor(() => {
      expect(screen.getByText('John')).toBeInTheDocument();
    });
  });
});

// Create mock data
const mockUser = createMockUser({
  firstName: 'Test',
  roles: ['admin'],
});

const mockPaged = createMockPagedResult([item1, item2], {
  page: 1,
  pageSize: 20,
  totalItems: 100,
});

API Reference

Core Classes

| Class | Description | |-------|-------------| | HttpClient | HTTP client for API requests with interceptors and retry logic | | AuthManager | Authentication state management with automatic token refresh | | PermissionManager | Role-based and feature-based access control | | PresenceClient | SignalR presence tracking hub client | | ApplicationLogsClient | SignalR application logs streaming client | | ApiLogsClient | SignalR API request logs streaming client | | QueryLogsClient | SignalR database query logs streaming client | | DashboardClient | SignalR dashboard statistics client | | ErrorHandler | Global error handling with custom error types | | ~~RealtimeClient~~ | ⚠️ Deprecated - Use SignalR-based clients instead |

React Hooks

Core Hooks

| Hook | Description | |------|-------------| | useCCMS() | Access full SDK context | | useAuth() | Authentication state and actions | | useHttpClient() | HTTP client instance | | usePermissions() | Permission manager instance |

API Hooks

| Hook | Description | |------|-------------| | useQuery() | Data fetching with caching | | useMutation() | Data mutations | | useInfiniteQuery() | Paginated/infinite data | | usePrefetch() | Prefetch data for navigation |

Service Hooks

| Hook | Services | Description | |------|----------|-------------| | useTaskServices() | 12 | Task, TaskStatus, TaskPriority, TaskAssignment, TaskComment, TaskNotification, etc. | | useUsersServices() | 9 | User, Role, Right, Auth, Audit, Admin, System, UserPreferences, UserPushDevice | | useMembersServices() | 9 | Member, Family, MemberType, MaritalStatus, MemberAddress, Allergy, Disability, etc. | | useMeetingsServices() | 14 | Meeting, MeetingStatus, MeetingType, MeetingVenue, MeetingAttendee, MeetingSetup, etc. | | useLocationsServices() | 8 | Location, Address, LocationInfo, LocationLeader, LocationVenue, ServiceTime, etc. | | useFileServices() | 2 | File, MultipartUpload | | useCommunicationServices() | 6 | Email, Sms, PushNotification, WhatsApp, Template, Device | | useSupplierServices() | 4 | Supplier, SupplierCategory, SupplierContact, SupplierNote | | useResourcesServices() | 8 | Course, CourseCategory, CourseSession, UsageLog, CourseStatus, etc. | | useProjectsServices() | 17 | Project, ProjectStatus, ProjectMilestone, ProjectTeamMember, TaskTimeLog, etc. | | useProcurementsServices() | 18 | PurchaseRequest, Quotation, Invoice, RequestAttachment, SagePurchaseOrder, etc. | | useProductsServices() | 8 | Product, ProductType, ProductColor, ProductSize, ProductStock, etc. | | usePaymentServices() | 14 | PaymentTransaction, Payer, Settlement, Refund, BillingAgreement, PayFast, etc. | | useOrderServices() | 6 | Order, OrderLine, OrderPayment, OrderStatus, PaymentStatus, OrderNotification | | useHrServices() | 19 | Employee, Leave, Duty, EmployeeFile, LeaveDocument, Policy, etc. | | useDepartmentsServices() | 10 | Department, Designation, Ministry, MinistryActivity, MinistryRole, etc. | | useFeedbackServices() | 5 | Feedback, FeedbackCategory, FeedbackType, FeedbackNotification, etc. | | useSystemServices() | 10 | System, ApiRequestLog, QueryPerformanceLog, Health, RabbitMQ, Redis, etc. | | useGeneratorsServices() | 4 | Barcode, QrCode, UtilityCode, GeneratedCode |

Realtime Hooks - Presence (4 hooks)

| Hook | Return Type | Description | |------|-------------|-------------| | usePresence() | { state, updateStatus, getUserPresence, getOnlineUsers, getAllPresence } | Main presence hook with full state and methods | | usePresenceStatus() | PresenceStatus | Get current user's presence status (Online/Away/Busy/Offline) | | useOnlineUsers() | UserPresenceUpdate[] | Get array of all currently online users | | useUserPresence(userId) | UserPresenceUpdate \| null | Get specific user's real-time presence information |

Presence State includes: isConnected, currentUserPresence, onlineUsers (Map), connectionError

Realtime Hooks - Logs (4 hooks)

| Hook | Return Type | Description | |------|-------------|-------------| | useApplicationLogs(options) | { logs, isConnected, subscribe, unsubscribe, clearLogs, loadRecent, ... } | Stream application logs with filtering (errors, warnings, info) | | useApiLogs(options) | { logs, isConnected, subscribe, unsubscribe, ... } | Stream API request logs (HTTP requests, responses, performance) | | useQueryLogs(options) | { logs, isConnected, subscribe, unsubscribe, ... } | Stream database query logs (query performance, slow queries) | | useDashboard(options) | { stats, refreshStats, getLogsByCorrelationId, getRecentErrors, ... } | Real-time system statistics and aggregated metrics |

Common Options: autoConnect, filter (serviceNames, logLevels, etc.), maxBufferSize, autoLoadRecent, onLog

Utility Hooks

| Hook | Description | |------|-------------| | useDebounce() | Debounced values | | useThrottle() | Throttled values | | usePrevious() | Previous value tracking | | useStorage() | Cross-platform storage | | useNetworkStatus() | Online/offline detection | | useToggle() | Boolean state toggle | | useCounter() | Counter with min/max | | useArray() | Array state operations | | useMap() | Map state operations | | useInterval() | Declarative intervals | | useTimeout() | Declarative timeouts | | useMediaQuery() | Responsive media queries | | useClipboard() | Clipboard operations | | useClickOutside() | Click outside detection | | useKeyPress() | Keyboard shortcuts |

Upload Hooks

| Hook | Description | |------|-------------| | useFileUpload() | File upload with progress | | useMultipartUpload() | Large file multipart upload |

React Components

| Component | Description | |-----------|-------------| | CCMSProvider | Root provider component | | Can | Feature-based rendering | | RequireAuth | Authentication guard | | RequireRole | Role-based rendering | | RequireRight | Permission-based rendering | | ErrorBoundary | Error boundary with fallback |


Deprecation Notices

Legacy Realtime Module

The original RealtimeClient and related hooks are deprecated and will be removed in version 2.0.0.

Deprecated APIs

  • RealtimeClient class
  • useConnectionState() hook
  • useRealtimeConnection() hook
  • useRealtimeEvent() hook
  • useRealtimeMessage() hook
  • useRealtimeSend() hook
  • useRealtimeGroup() hook
  • Legacy usePresence() hook

Migration Path

| Old API | New API | Module | |---------|---------|--------| | RealtimeClient | PresenceClient, ApplicationLogsClient, etc. | @actschurch/ccms-sdk/realtime/* | | useConnectionState() | usePresence().state | @actschurch/ccms-sdk/realtime/presence | | usePresence() | usePresence() (new API) | @actschurch/ccms-sdk/realtime/presence | | useRealtimeEvent() | useApplicationLogs(), useApiLogs(), etc. | @actschurch/ccms-sdk/realtime/logs |

For detailed migration instructions, see the Realtime Module Documentation.


License

MIT License - see LICENSE for details.


Support