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

flagsup-ts

v1.1.0

Published

Flagsup sdk (written in ts)

Readme

flagsup-ts

flagsup-ts is a TypeScript package for managing feature flags in TypeScript projects. It offers a flexible and efficient solution for implementing feature flagging strategies, allowing developers to control feature rollout and experimentation with ease.

Installation

Use the package manager yarn or npm to install the package

# Yarn
yarn add flagsup-ts
# NPM
npm install flagsup-ts

Features

  • TypeScript Support: Built specifically for TypeScript projects, ensuring type safety and enhanced developer experience
  • Dynamic EntityId Configuration: Support for both static and dynamic entityId configurations, enabling flexible flag evaluation based on user context
  • Dual Client Architecture: Choose between FlagsupClient (traditional class) or FlagsupClientBuilder (builder pattern) based on your needs
  • Advanced Caching: Multiple caching strategies including in-memory, localStorage, and stale-while-revalidate patterns
  • Real-time Updates: Subscribe to flag changes for reactive applications
  • Retry Logic: Built-in retry mechanisms with exponential backoff

Quick Start

FlagsupClient (Traditional)

import FlagsupClient from "flagsup-ts";

// Create client with configuration
const client = new FlagsupClient({
  targetHostname: "https://flagsup.tekoapis.com",
  defaultEntityId: "user123",
  useCacheRefresh: true,
  refreshInterval: 60,
});

// Evaluate flags
const result = await client.batchEvaluateFlags({
  feature_a: "user123",
  feature_b: {
    key: "feature_b",
    entityId: "user456"
  },
  feature_c: {
    key: "key_with_dynamic_entity_id",
    getEntityId: (currentUser) => currentUser?.meta_data?.seller_id,
  },
});

console.log("Flags:", result.flags);

FlagsupClientBuilder (Builder Pattern)

import { FlagsupClientBuilder } from "flagsup-ts";

// Configure with fluent API
const client = new FlagsupClientBuilder()
  .setTargetHostname("https://flagsup.tekoapis.com")
  .setDefaultEntityId("user123")
  .setMaxRetries(3)
  .setAllowUseStaleTime(300);

// Subscribe to updates
const unsubscribe = client.subscribe((flags) => {
  console.log("Flags updated:", flags);
});

// Get flags with caching
const result = await client.getFlags({
  feature_a: "user123",
  feature_b: {
    key: "feature_b",
    entityId: "user456"
  },
  feature_c: {
    key: "key_with_dynamic_entity_id",
    getEntityId: (currentUser) => currentUser?.meta_data?.seller_id,
  },
});

unsubscribe();

Clients

FlagsupClient

The FlagsupClient class provides a traditional approach to feature flag management with in-memory caching and optional auto-refresh capabilities.

Configuration

const client = new FlagsupClient({
  targetHostname: "https://flagsup.tekoapis.com",     // API hostname
  defaultEntityId: "user123",                        // Default entity ID
  clientInstanceName: "MyFlagsupClient",             // Global window object name
  refreshInterval: 30,                               // Auto-refresh interval (seconds)
  useCacheRefresh: true                              // Enable auto-refresh
});

Key Methods

  • evaluateFlag(flagKey, entityId?, options?): Evaluate single flag
  • batchEvaluateFlags(flagKeys, getEntityIdDataSource?, defaultResponse?): Evaluate multiple flags
  • getFlagStatus(flagKey, defaultStatus?): Get flag enabled/disabled status
  • batchGetFlagsStatus(flagKeys, defaultStatus?): Get status for multiple flags
  • flushCache(): Clear all cached data

React Example

import React, { useState, useEffect } from 'react';
import FlagsupClient from 'flagsup-ts';

const client = new FlagsupClient({
  targetHostname: 'https://flagsup.tekoapis.com',
  defaultEntityId: 'user123',
  useCacheRefresh: true,
  refreshInterval: 30,
});

function FeatureComponent() {
  const [flags, setFlags] = useState({});
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchFlags = async () => {
      const result = await client.batchEvaluateFlags({
        'new_dashboard': 'user123',
        'dark_mode': 'user123',
        'beta_features': 'user123'
      });

      if (!result.error) {
        setFlags(result.flags);
      }
      setLoading(false);
    };

    fetchFlags();
  }, []);

  if (loading) return <div>Loading...</div>;

  return (
    <div>
      <h1>Dashboard</h1>
      {flags.new_dashboard?.enabled && <div>New Dashboard Available!</div>}
      {flags.dark_mode?.enabled && <div>Dark Mode: {flags.dark_mode.treatment}</div>}
    </div>
  );
}

FlagsupClientBuilder

The FlagsupClientBuilder uses a builder pattern for configuration and provides advanced caching with localStorage, retry logic, and real-time subscriptions.

Configuration

const client = new FlagsupClientBuilder()
  .setTargetHostname("https://flagsup.tekoapis.com")  // Required
  .setDefaultEntityId("user123")                      // Optional
  .setMaxRetries(3)                                   // Optional, default: 1
  .setAllowUseStaleTime(300)                          // Optional, default: 0
  .setEnableLogging(true);                            // Optional, default: false

Key Methods

  • subscribe(callback): Subscribe to flag updates, returns unsubscribe function
  • getFreshFlags(flagKeys, getEntityIdDataSource?): Fetch fresh flags bypassing cache
  • getFlags(flagKeys, getEntityIdDataSource?): Smart fetch using cache when available

React Example with Real-time Updates

import React, { useState, useEffect } from 'react';
import { FlagsupClientBuilder } from 'flagsup-ts';

const client = new FlagsupClientBuilder()
  .setTargetHostname('https://flagsup.tekoapis.com')
  .setDefaultEntityId('user123')
  .setMaxRetries(3)
  .setAllowUseStaleTime(300)
  .setEnableLogging(true);

function FeatureFlagComponent() {
  const [flags, setFlags] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    // Subscribe to real-time flag updates
    const unsubscribe = client.subscribe(setFlags);

    // Initial flag fetch
    const fetchInitialFlags = async () => {
      try {
        const result = await client.getFlags({
          'feature_a': 'user123',
          'feature_b': { key: 'feature_b', entityId: 'user456' }
        });

        if (result.error) {
          setError(result.error);
        } else {
          setFlags(result.flags);
        }
      } catch (err) {
        setError('Failed to fetch flags');
      } finally {
        setLoading(false);
      }
    };

    fetchInitialFlags();

    return unsubscribe; // Cleanup on unmount
  }, []);

  if (loading) return <div>Loading flags...</div>;
  if (error) return <div>Error: {error}</div>;
  if (!flags) return <div>No flags available</div>;

  return (
    <div>
      <h2>Feature Flags</h2>
      <div>Feature A: {flags.feature_a?.enabled ? 'Enabled' : 'Disabled'}</div>
      <div>Feature B: {flags.feature_b?.enabled ? 'Enabled' : 'Disabled'}</div>
      <div>Treatment A: {flags.feature_a?.treatment}</div>
    </div>
  );
}

Data Types

Flag Configuration

// Simple string (uses default entity ID)
const config1 = "flag_key";

// With static entity ID
const config2 = {
  key: "flag_key",
  entityId: "static_id"
};

// With dynamic entity ID
const config3 = {
  key: "flag_key",
  getEntityId: (user) => user.id
};

// Combined configuration object
const flagKeys = {
  feature_a: "user123",
  feature_b: config2,
  feature_c: config3
};

Flag Response Data

interface EvaluatedFlagData {
  enabled: boolean;
  expId: number;
  treatment: string;
  expBranchId: number;
}

interface EvaluatedFlagsData {
  [flagKey: string]: EvaluatedFlagData;
}

Advanced Usage

Dynamic Entity IDs

// For user-specific flags
const userFlags = await client.batchEvaluateFlags({
  'premium_features': {
    key: 'premium_features',
    getEntityId: (user) => user.id
  },
  'geo_specific': {
    key: 'geo_specific',
    getEntityId: (user) => user.country
  }
}, currentUser);

Error Handling

const result = await client.getFlags(flagKeys);

if (result.error) {
  console.error('Flag evaluation failed:', result.error);
  // Fallback logic
} else {
  // Use result.flags
}