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

@merittdev/sdk

v0.1.3

Published

SDK for Meritt Engine content management with Firebase integration

Readme

Meritt SDK - Development Context & Architecture

Quality Pipeline This document provides comprehensive context about the Meritt SDK development, architectural decisions, and implementation details for future reference.

Project Overview

Name: @merittdev/sdk
Purpose: A powerful SDK for Meritt Engine content management with Firebase integration
Architecture: Provider-only React SDK with TypeScript
State Management: Zustand stores
Database: Firebase Firestore

Key Architectural Decisions

1. Provider-Only Architecture (Final Decision)

Decision: Use React Provider pattern exclusively, removing global initializeSDK() function.

Rationale:

  • ✅ Cleaner API - just wrap with provider
  • ✅ Multiple instances support (multi-tenant apps)
  • ✅ Better testing - easy to mock with different configs
  • ✅ React-first approach - follows React patterns
  • ✅ Type safety - hooks require provider context
  • ✅ Clear error handling - helpful errors if provider missing

Implementation:

// Client usage
;<MerittProvider config={firebaseConfig}>
  <App />
</MerittProvider>

// Inside components
const { products, loading } = useProducts({ featured: true })

Alternative Considered: Hybrid approach with both initializeSDK() and provider, but rejected for complexity.

2. Firebase Instance Management

Decision: Each provider creates its own Firebase app instance with unique names.

Implementation:

  • Provider creates Firebase app with namespace: meritt-${namespace} or meritt-default
  • Firebase instances (db, auth, storage) passed to all store methods
  • No global Firebase state - everything context-based

Benefits:

  • Multiple Firebase projects in same app
  • Isolated instances for testing
  • No singleton issues

3. Store Architecture

Decision: Zustand stores that accept Firebase instances as parameters.

Pattern:

// Store method signature
fetchProducts: (options: ProductQueryOptions, firebase: FirebaseInstances) =>
  Promise<Product[]>

// Hook usage
const { firebase } = useMerittContext()
await fetchProducts(options, firebase)

Benefits:

  • Works with provider pattern
  • Testable with mock Firebase instances
  • No global dependencies

4. Firestore Indexes Strategy

Decision: Include firestore.indexes.json file in npm package for manual deployment.

Alternatives Considered:

  1. ❌ Automated setup script - too complex
  2. ❌ Manual console creation - too error-prone
  3. ✅ JSON file + Firebase CLI - simple and standard

Client Setup:

cp node_modules/@merittdev/sdk/firestore.indexes.json .
firebase deploy --only firestore:indexes

File Structure

src/
├── index.ts                    # Main exports
├── providers/
│   └── MerittProvider.tsx     # React provider + context hooks
├── hooks/
│   ├── useProducts.ts         # Product management hook
│   ├── useMedia.ts           # Media management hook
│   ├── useUpload.ts          # File upload hook
│   ├── useSettings.ts        # Settings management hook
│   ├── useCategories.ts      # Categories management hook
│   └── useCart.ts            # Shopping cart hook
├── stores/
│   ├── productStore.ts       # Zustand product store
│   ├── mediaStore.ts         # Zustand media store
│   ├── settingsStore.ts      # Zustand settings store
│   └── cartStore.ts          # Zustand cart store
├── services/
│   ├── productService.ts     # Direct Firebase product operations
│   └── categoryService.ts    # Direct Firebase category operations
├── utils/
│   ├── firebaseContext.ts    # Firebase instance utilities
│   ├── contentUtils.ts       # Content/Firestore utilities
│   ├── mediaUtils.ts         # Media/file utilities
│   ├── formatters.ts         # Text and data formatting utilities
│   └── cartUtils.ts          # Shopping cart utilities
├── config/
│   └── firebase.ts           # Firebase configuration
└── types.ts                  # TypeScript type definitions

firestore.indexes.json         # Firestore composite indexes
package.json                   # NPM package configuration
README.md                     # User documentation

Core Components

MerittProvider

Purpose: Initialize Firebase and provide context to child components.

Key Features:

  • Creates unique Firebase app instances
  • Provides Firebase instances to hooks
  • Handles initialization state and errors
  • Supports multiple instances with namespaces

Exports:

  • MerittProvider - Main provider component
  • useMerittContext() - Access provider context
  • useFirebaseInstances() - Direct Firebase access

Content Hooks

Available Hooks:

  • useProducts(options) - Product management
  • useMedia(options) - Media management
  • useUpload() - File upload functionality
  • useSettings(options) - Settings management
  • useCategories(options) - Category management
  • useCart(options) - Shopping cart functionality

Pattern:

  • All hooks require MerittProvider
  • Get Firebase instances from context
  • Pass instances to store methods
  • Handle loading/error states

Zustand Stores

Architecture:

  • Store methods accept Firebase instances as parameters
  • No global Firebase dependencies
  • Maintain local state (products, loading, error)
  • Provide CRUD operations

Example Store Method:

fetchProducts: async (
  options: ProductQueryOptions,
  firebase: FirebaseInstances,
) => {
  // Use firebase.db for Firestore operations
  // Update store state
  // Return results
}

Type System

Core Types

Content Types:

  • Product - E-commerce product
  • Article - Blog article
  • PortfolioProject - Portfolio project
  • Media - Media asset
  • Category - Content category
  • Order - E-commerce order
  • Cart - Shopping cart
  • CartItem - Shopping cart item

Query Types:

  • ProductQueryOptions - Product filtering options
  • MediaQueryOptions - Media filtering options
  • ArticleQueryOptions - Article filtering options
  • PortfolioProjectQueryOptions - Portfolio project filtering options
  • CartQueryOptions - Cart filtering options
  • SettingsQueryOptions - Settings filtering options

Firebase Types:

  • FirebaseInstances - Firebase service instances
  • MerittConfig - Firebase configuration

Project Generator Types:

  • ProjectConfiguration - Complete project configuration
  • ProjectMetadata - Project metadata
  • PageDefinition - Page definition
  • ComponentPlacement - Component placement
  • SectionSelection - Section selection
  • ThemeConfiguration - Theme configuration
  • SiteConfiguration - Site configuration
  • ComponentMapping - Component mapping
  • GenerationOptions - Generation options
  • GeneratedFile - Generated file
  • GenerationResult - Generation result
  • GenerationSummary - Generation summary
  • TemplateContext - Template context
  • ComponentInstance - Component instance

Firestore Schema

Collections

Products Collection:

{
  id: string;
  name: string;
  slug: string;
  price: number;
  salePrice?: number;
  description: string;
  shortDescription?: string;
  images: string[];
  categories: string[];
  tags?: string[];
  inStock: boolean;
  quantity?: number;
  variants?: ProductVariant[];
  attributes?: Record<string, string>;
  featured?: boolean;
  relatedProducts?: string[];
  createdAt: Timestamp;
  updatedAt: Timestamp;
}

Articles Collection:

{
  id: string;
  title: string;
  slug: string;
  content: string;
  excerpt?: string;
  coverImage?: string;
  author: string;
  publishedDate: Timestamp;
  categories: string[];
  tags?: string[];
  isPublished: boolean;
  isFeatured?: boolean;
  readTime?: number;
  createdAt: Timestamp;
  updatedAt: Timestamp;
}

Media Collection:

{
  id: string;
  fileName: string;
  fileType: string;
  fileSize: number;
  url: string;
  thumbnailUrl?: string;
  alt?: string;
  caption?: string;
  width?: number;
  height?: number;
  folder?: string;
  tags?: string[];
  createdAt: Timestamp;
  updatedAt: Timestamp;
}

Categories Collection:

{
  id: string;
  name: string;
  slug: string;
  description?: string;
  parentId?: string;
  image?: string;
  createdAt: Timestamp;
  updatedAt: Timestamp;
}

Carts Collection:

{
  id: string;
  userId?: string;
  sessionId?: string;
  items: CartItem[];
  subtotal: number;
  itemCount: number;
  discount: number;
  discountCode?: string;
  currency: string;
  createdAt: Timestamp;
  updatedAt: Timestamp;
  expiresAt?: Timestamp;
}

Settings Collection:

{
  id: string;
  theme: ThemeConfig;
  sidebarCollapsed: boolean;
  language: string;
  timezone: string;
  branding?: BrandingConfig;
  ui?: UIPreferences;
  localization?: LocalizationPreferences;
  notifications?: NotificationPreferences;
  security?: SecurityPreferences;
  projectInfo?: ProjectInfo;
}

Required Indexes

Products:

  • featured + createdAt
  • inStock + createdAt
  • featured + inStock + createdAt
  • categories (array-contains) + createdAt
  • categories (array-contains) + featured + createdAt

Articles:

  • isPublished + createdAt
  • isFeatured + createdAt
  • categories (array-contains) + isPublished + createdAt

Media:

  • fileType + createdAt
  • folder + createdAt
  • tags (array-contains) + createdAt

Carts:

  • userId + updatedAt
  • sessionId + updatedAt
  • expiresAt + updatedAt

Development Decisions Log

Provider vs Initialize Function Debate

Initial Approach: Global initializeSDK() function Problem: Not React-friendly, no multiple instances, testing issues Solution: Provider-only architecture Result: Cleaner, more flexible, better DX

Store Parameter Passing

Challenge: How to get Firebase instances to stores? Options:

  1. Global Firebase instances (rejected - not provider-friendly)
  2. Store methods accept Firebase parameters (chosen)
  3. Context-aware stores (rejected - too complex)

Implementation: All store methods accept firebase: FirebaseInstances parameter

Index Management Strategy

Challenge: How to handle Firestore composite indexes? Options:

  1. Automated script with deployment (rejected - too complex)
  2. Manual console creation (rejected - error-prone)
  3. JSON file + Firebase CLI (chosen - simple, standard)

Result: Include firestore.indexes.json in package, document copy+deploy process

Shopping Cart Implementation

Challenge: How to handle guest carts vs user carts? Solution:

  • Use userId for logged-in users
  • Use sessionId for guest users
  • Merge carts on login

Implementation:

  • Flexible cart store with session management
  • Cart persistence in Firestore
  • Cart expiration for guest carts

Error Handling Philosophy

Approach: Fail fast with helpful error messages Examples:

  • Hook used outside provider: Clear error with setup instructions
  • Firebase not initialized: Specific error about provider setup
  • Missing indexes: Point to documentation

Testing Strategy

Local Development

Setup:

npm link                    # In SDK directory
cd /path/to/test-project
npm link @merittdev/sdk   # In test project

Test Pattern:

<MerittProvider config={testFirebaseConfig}>
  <TestComponent />
</MerittProvider>

Multiple Instances Testing

<MerittProvider config={tenant1Config} namespace="tenant1">
  <TenantApp />
</MerittProvider>
<MerittProvider config={tenant2Config} namespace="tenant2">
  <TenantApp />
</MerittProvider>

Performance Considerations

Query Optimization

  • All queries use composite indexes
  • Pagination with startAfter cursors
  • Limit queries to reasonable sizes
  • Cache results in Zustand stores

Firebase Optimization

  • Unique app names prevent conflicts
  • Minimal Firebase SDK imports
  • Efficient query patterns

Project Generator

The SDK includes a powerful project generator for creating new Meritt Engine projects.

Key Features:

  • Dynamic page generation based on project configuration
  • Component selection and customization
  • Theme configuration
  • Firebase integration
  • TypeScript type safety

Generation Process:

  1. Load project configuration from Firestore
  2. Process component selections and customizations
  3. Generate files based on templates
  4. Apply customizations to components
  5. Set up Firebase configuration
  6. Generate necessary configuration files

E-commerce Features

The SDK provides comprehensive e-commerce functionality:

Product Management:

  • Product CRUD operations
  • Product variants
  • Product categories
  • Product search and filtering

Shopping Cart:

  • Add to cart
  • Update cart items
  • Remove from cart
  • Cart persistence
  • Guest carts
  • Cart merging on login
  • Cart expiration

Order Processing:

  • Order creation
  • Order status management
  • Order history

Future Considerations

Potential Enhancements

  1. Offline Support: Add Firebase offline persistence
  2. Real-time Updates: WebSocket/Firestore listeners
  3. Caching Strategy: More sophisticated caching
  4. Authentication: Built-in auth hooks
  5. File Upload: Progress tracking, resumable uploads
  6. Analytics Integration: User behavior tracking
  7. Payment Processing: Integration with payment gateways
  8. Internationalization: Multi-language support
  9. Advanced Search: Full-text search capabilities
  10. Webhooks: Event-driven integrations

Breaking Changes to Avoid

  • Don't change store method signatures
  • Don't remove provider pattern
  • Don't change core type definitions
  • Don't modify index requirements without migration

Troubleshooting Guide

Common Issues

"useMerittContext must be used within a MerittProvider"

  • Solution: Wrap app with <MerittProvider>

"Firebase not initialized"

  • Solution: Check provider config, ensure valid Firebase credentials

"Index not found" errors

  • Solution: Deploy firestore.indexes.json file

Products not loading

  • Check: Firebase config, indexes deployed, documents exist, console errors

Debug Steps

  1. Check provider setup and config
  2. Verify Firebase project access
  3. Confirm indexes are built
  4. Check browser console for errors
  5. Verify document structure matches types

Deployment Checklist

Before Publishing

  • [ ] Run npm run build
  • [ ] Test with npm link in real project
  • [ ] Verify firestore.indexes.json included
  • [ ] Update version in package.json
  • [ ] Update README if needed
  • [ ] Test index deployment process

Publishing

npm run build
npm publish

Post-Publishing

  • [ ] Test installation: npm install @merittdev/sdk
  • [ ] Verify files included in package
  • [ ] Test index setup process
  • [ ] Update documentation if needed

Integration with Meritt Engine Dashboard

The SDK is designed to work seamlessly with the Meritt Engine Dashboard:

Dashboard Features:

  • Visual interface for content management
  • Real-time data synchronization
  • User authentication and authorization
  • File upload and management
  • Analytics and reporting
  • Settings management

Integration Points:

  • SDK provides data layer for dashboard
  • Dashboard uses SDK hooks for data fetching
  • Dashboard uses SDK types for type safety
  • Dashboard uses SDK utilities for formatting and validation

Contact & Support

Repository: https://github.com/merittdev/sdk
Issues: https://github.com/merittdev/sdk/issues
Support: [email protected]


This document should be updated whenever significant architectural decisions are made or implementation details change.