flagcraft 0.1.0 โ†’ 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +163 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # ๐Ÿ“ฆ FlagCraft SDK (`flagcraft`)
2
+
3
+ [![npm version](https://img.shields.io/npm/v/flagcraft.svg?color=blue)](https://www.npmjs.com/package/flagcraft)
4
+ [![npm bundle size](https://img.shields.io/bundlephobia/minzip/flagcraft.svg?color=green)](https://bundlephobia.com/package/flagcraft)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
7
+
8
+ The official, ultra-fast, universal **TypeScript / JavaScript SDK** for [FlagCraft](https://github.com/Akash-1808/feature-flag), engineered for high-concurrency environments, zero-latency local evaluations, conditional ETag polling, and fail-open resilience.
9
+
10
+ ---
11
+
12
+ ## โœจ Why FlagCraft SDK?
13
+
14
+ Standard feature flag SDKs make blocking HTTP requests on every evaluation or download massive JSON payloads repeatedly. **`flagcraft`** is built differently:
15
+
16
+ - **โšก Zero-Latency Local Evaluations (`0ms`)**: Rulesets are stored in an ultra-fast in-memory cache (`InMemoryCache`). Calling `flagcraft.evaluate()` executes entirely in local CPU memory without blocking network calls or disk I/O.
17
+ - **๐Ÿ“‰ ETag Conditional Polling (`>95% Bandwidth Saved`)**: When background polling checks for updates, the SDK sends an `If-None-Match: W/"hash"` header. If no flag rules changed in the management dashboard, the FlagCraft server returns a zero-byte **`HTTP 304 Not Modified`** response instantly.
18
+ - **๐ŸŽฏ Deterministic MurmurHash3 Bucketing**: When rolling out a feature to `30%` of users (`rollout_percentage = 30`), `flagcraft` calculates `MurmurHash3(flagKey + userId) % 100`. This guarantees the exact same user gets the identical experience across all distributed servers with **zero UI flickering**.
19
+ - **๐Ÿ›ก๏ธ Fail-Open & Tiered Fallback Cache**: If your central FlagCraft API or database goes offline during a major cloud outage, the SDK falls back to cached local rules or your safe code defaults (`isEnabled = false`). Your application **never crashes** due to flag evaluation failures.
20
+ - **๐Ÿ“Š Auto-Rollback Telemetry**: Automatically batches and reports evaluation metrics and error cohorts back to FlagCraft (`MetricsWatcher`), allowing automated circuit breakers to trip within seconds if an anomaly occurs.
21
+
22
+ ---
23
+
24
+ ## ๐Ÿ“ฆ Installation
25
+
26
+ Install `flagcraft` via your preferred package manager:
27
+
28
+ ```bash
29
+ npm install flagcraft
30
+ ```
31
+ ```bash
32
+ yarn add flagcraft
33
+ ```
34
+ ```bash
35
+ pnpm add flagcraft
36
+ ```
37
+
38
+ ---
39
+
40
+ ## ๐Ÿš€ Quickstart Guide
41
+
42
+ ### 1. Initialize the SDK
43
+ Create a single instance of `FlagCraft` during your server or application startup:
44
+
45
+ ```typescript
46
+ import { FlagCraft } from 'flagcraft';
47
+
48
+ // Initialize with your Environment API Key from FlagCraft Dashboard
49
+ const flagcraft = new FlagCraft({
50
+ apiKey: 'server_abc123_your_secret_key', // Or client_... for frontend apps
51
+ baseUrl: 'http://localhost:3001', // Your running FlagCraft API server
52
+ pollingInterval: 30000, // Check for rule changes every 30 seconds
53
+ fallbackFlags: {
54
+ 'new-ai-search': false, // Safe defaults if API is unreachable on initial boot
55
+ },
56
+ });
57
+
58
+ // Start the background ETag polling engine
59
+ await flagcraft.init();
60
+ ```
61
+
62
+ ---
63
+
64
+ ### 2. Evaluate Feature Flags Instantly (`0ms` Latency)
65
+
66
+ Pass the flag key and targeting context (`userId`, `attributes`):
67
+
68
+ ```typescript
69
+ // Example: Inside an Express, Next.js, or Fastify route controller
70
+ app.get('/search', async (req, res) => {
71
+ const userId = req.headers['x-user-id'] || 'guest_user';
72
+
73
+ // Instant local memory check (Zero network latency!)
74
+ const useAiSearch = flagcraft.evaluate('new-ai-search', {
75
+ userId: userId,
76
+ attributes: {
77
+ country: 'US',
78
+ plan: 'pro',
79
+ appVersion: '2.4.0',
80
+ },
81
+ });
82
+
83
+ if (useAiSearch) {
84
+ return res.json({ status: 'success', engine: 'AI Search Engine v2 โœจ' });
85
+ } else {
86
+ return res.json({ status: 'success', engine: 'Standard SQL Search Engine' });
87
+ }
88
+ });
89
+ ```
90
+
91
+ ---
92
+
93
+ ### 3. Evaluate All Flags for a User (e.g., Initializing Frontend State)
94
+
95
+ If you need to return all flag states for a specific user in a single request:
96
+
97
+ ```typescript
98
+ app.get('/api/user/flags', (req, res) => {
99
+ const allFlags = flagcraft.evaluateFlags({
100
+ userId: req.query.userId as string,
101
+ attributes: { country: 'UK' },
102
+ });
103
+
104
+ // Returns: { 'new-ai-search': true, 'dark-mode-v2': false, ... }
105
+ res.json(allFlags);
106
+ });
107
+ ```
108
+
109
+ ---
110
+
111
+ ## โš™๏ธ Configuration Options
112
+
113
+ | Option | Type | Default | Description |
114
+ | :--- | :--- | :--- | :--- |
115
+ | **`apiKey`** *(required)* | `string` | โ€” | Your FlagCraft environment API key (`server_...` or `client_...`). |
116
+ | **`baseUrl`** | `string` | `'http://localhost:3001'` | The HTTP URL where your FlagCraft control-plane API is deployed. |
117
+ | **`pollingInterval`** | `number` | `30000` | Frequency in milliseconds for ETag background polling (`min: 1000ms`). |
118
+ | **`fallbackFlags`** | `Record<string, boolean>` | `{}` | Static fallbacks used before initial fetch or during network outages. |
119
+ | **`onError`** | `(err: Error) => void` | `console.error` | Custom error callback for background polling failures or network timeouts. |
120
+
121
+ ---
122
+
123
+ ## ๐Ÿ“š API Reference
124
+
125
+ ### `flagcraft.init(): Promise<void>`
126
+ Boots the background `Poller` and performs the initial ruleset fetch. Resolves immediately when the initial ruleset is loaded into the `InMemoryCache` or gracefully falls back to `fallbackFlags`.
127
+
128
+ ### `flagcraft.evaluate(flagKey: string, context?: EvaluationContext): boolean`
129
+ Evaluates a single feature flag synchronously using the cached ruleset.
130
+ - **`flagKey`**: The unique identifier of the flag (e.g., `'new-checkout'`).
131
+ - **`context.userId`**: Required for percentage-based rollouts to ensure deterministic hashing.
132
+ - **`context.attributes`**: Key-value pairs (`{ country: 'US', tier: 'gold' }`) evaluated against custom targeting rules (`CONTAINS`, `EQUALS`, `IN`, `GREATER_THAN`).
133
+
134
+ ### `flagcraft.evaluateFlags(context?: EvaluationContext): Record<string, boolean>`
135
+ Evaluates every active feature flag in the environment for the provided context and returns a dictionary mapping flag keys to boolean outcomes.
136
+
137
+ ### `flagcraft.close(): void`
138
+ Stops background polling intervals and clears the memory cache. Call this during graceful server shutdown (`SIGTERM` / `SIGINT`).
139
+
140
+ ---
141
+
142
+ ## ๐Ÿงช Advanced: ETag Polling Under the Hood
143
+
144
+ When `flagcraft` polls your FlagCraft server (`GET /sdk/flags`), it passes the MD5 hash of the active ruleset inside the `If-None-Match` HTTP header:
145
+
146
+ ```http
147
+ GET /sdk/flags HTTP/1.1
148
+ Host: localhost:3001
149
+ x-api-key: server_e24dfb98_secret
150
+ If-None-Match: W/"a9f8c7e6b5d4c3b2a1"
151
+ ```
152
+
153
+ If the ruleset hasn't changed since the last fetch, the server replies with:
154
+ ```http
155
+ HTTP/1.1 304 Not Modified
156
+ ```
157
+ This design allows thousands of distributed servers or serverless containers to poll frequently (`e.g., every 5-10s`) with **near-zero CPU and network overhead**.
158
+
159
+ ---
160
+
161
+ ## ๐Ÿ“ License
162
+
163
+ Distributed under the MIT License. Built with โค๏ธ for enterprise reliability and speed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flagcraft",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Universal, fail-open feature flag evaluation SDK with ETag conditional caching and auto-rollback support.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",