Skip to content
This repository was archived by the owner on Feb 15, 2026. It is now read-only.

Comments

feat: Feature flags#23

Merged
Blaumaus merged 5 commits intomainfrom
feature-flags
Dec 10, 2025
Merged

feat: Feature flags#23
Blaumaus merged 5 commits intomainfrom
feature-flags

Conversation

@Blaumaus
Copy link
Member

@Blaumaus Blaumaus commented Dec 8, 2025

Summary by CodeRabbit

  • New Features
    • Feature flags API: fetch feature flags with automatic 5-minute caching and option to force refresh.
    • Retrieve single flag with a default fallback.
    • Profile ID support: optional global or per-call profile identifiers for events and page views.
    • Cache management: manually clear the feature flags cache.

✏️ Tip: You can customize this high-level summary in your review settings.

@Blaumaus Blaumaus self-assigned this Dec 8, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 8, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Feature-flag support and profileId propagation were added. New public APIs fetch, cache, and clear feature flags; profileId can be set globally or per-call and is included in tracking/pageview payloads. Internal caching and API base resolution were introduced.

Changes

Cohort / File(s) Summary
Feature flags, profileId, and internal state
src/Lib.ts
Added profileId?: string to LibOptions, TrackEventOptions, and IPageViewPayload; added FeatureFlagsOptions and CachedFlags; added private cachedFlags and getApiBase(); introduced getFeatureFlags(options?, forceRefresh?), getFeatureFlag(key, options?, defaultValue?), and clearFeatureFlagsCache(); added DEFAULT_API_BASE and DEFAULT_CACHE_DURATION; include profileId in track/pageview payloads.
Public API surface for feature flags
src/index.ts
Re-exported FeatureFlagsOptions; added getFeatureFlags(), getFeatureFlag(), and clearFeatureFlagsCache() functions that delegate to the library instance and handle a null instance gracefully.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Client
    participant Lib
    participant Cache
    participant API as "API Server"

    Client->>Lib: getFeatureFlags(options, forceRefresh)
    Lib->>Cache: check cachedFlags (pid, age)
    alt cache valid and not forceRefresh
        Cache-->>Lib: return cached flags
    else cache miss/expired or forceRefresh
        Lib->>API: POST /feature-flag/evaluate { pid, profileId? }
        API-->>Lib: { flags: Record<string,bool> }
        Lib->>Cache: store flags + timestamp
        Cache-->>Lib: ack
    end
    Lib-->>Client: Promise<Record<string,bool>>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to: getFeatureFlags caching (timestamp math, DEFAULT_CACHE_DURATION), forceRefresh behavior, error handling and fallbacks, getApiBase() correctness (apiURL normalization), and profileId precedence (per-call over global).

Possibly related PRs

  • Profiles #22 — modifies profileId handling and payload propagation (overlapping changes).
  • feat: Feature flags #23 — adds feature-flag interfaces, cachedFlags, and the same public API surface (closely related).

Poem

🐰 I hopped in code where flags now bloom,

Five-minute caches chase away the gloom.
ProfileId tucked in each tiny trace,
Flags fetched swiftly from a distant place.
Tiny paws applaud this tidy space.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Feature flags' directly and clearly describes the main addition to the codebase—implementing a new feature flags subsystem with related API methods.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2977579 and fc41ce9.

📒 Files selected for processing (1)
  • src/Lib.ts (9 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Blaumaus Blaumaus mentioned this pull request Dec 8, 2025
9 tasks
@Blaumaus Blaumaus marked this pull request as ready for review December 10, 2025 23:14
@Blaumaus
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 10, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/Lib.ts (2)

439-445: Add timeout to fetch request.

The fetch call has no timeout, which could cause the request to hang indefinitely on slow or unresponsive networks.

Consider adding a timeout using AbortController:

+      const controller = new AbortController()
+      const timeoutId = setTimeout(() => controller.abort(), 10000) // 10 second timeout
+
       const response = await fetch(`${apiBase}/feature-flag/evaluate`, {
         method: 'POST',
         headers: {
           'Content-Type': 'application/json',
         },
         body: JSON.stringify(body),
+        signal: controller.signal,
       })
+
+      clearTimeout(timeoutId)

452-458: Consider validating response structure.

The code assumes the response has a flags property without validation. If the API returns an unexpected structure, accessing data.flags could fail.

Consider adding basic validation:

       const data = (await response.json()) as { flags: Record<string, boolean> }
 
+      if (!data || typeof data.flags !== 'object') {
+        console.warn('[Swetrix] Invalid response structure from feature flags API')
+        return this.cachedFlags?.flags || {}
+      }
+
       // Update cache
       this.cachedFlags = {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02ad5b8 and 2977579.

📒 Files selected for processing (2)
  • src/Lib.ts (9 hunks)
  • src/index.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/index.ts (1)
src/Lib.ts (4)
  • getFeatureFlags (416-465)
  • FeatureFlagsOptions (113-119)
  • getFeatureFlag (475-478)
  • clearFeatureFlagsCache (483-485)
src/Lib.ts (1)
src/utils.ts (1)
  • isInBrowser (17-19)
🔇 Additional comments (8)
src/index.ts (2)

153-178: LGTM!

The function correctly handles the null LIB_INSTANCE case by returning the defaultValue, and the JSDoc is accurate.


180-188: LGTM!

The cache-clearing function follows the established pattern and correctly handles the null LIB_INSTANCE case.

src/Lib.ts (6)

36-40: LGTM!

The profileId additions provide a clean global-with-override pattern. The implementation correctly uses the nullish coalescing operator in track (line 333) and allows spread override in submitPageView (line 555).

Also applies to: 55-56, 76-77


110-127: LGTM!

The interfaces are well-defined. FeatureFlagsOptions provides a clean API surface, and CachedFlags properly encapsulates the cache structure.


208-208: LGTM!

The constants are well-defined. A 5-minute cache duration is reasonable for feature flags, balancing freshness with API load.

Also applies to: 210-211


467-478: LGTM!

The method correctly delegates to getFeatureFlags and uses nullish coalescing to handle missing flag keys.


480-485: LGTM!

The cache-clearing logic is straightforward and correct.


487-496: LGTM!

The method correctly strips the /log suffix from custom API URLs, ensuring feature flag endpoints work with self-hosted instances.

@Blaumaus Blaumaus merged commit 47d89f6 into main Dec 10, 2025
1 check passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant