@nexussdk/flags 0.0.3 → 0.0.4
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.
- package/README.md +187 -8
- package/dist/chunk-VC3UFQ47.mjs +767 -0
- package/dist/dev-server/cli.mjs +95 -0
- package/dist/dev-server/index.mjs +11 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.global.js +3 -3
- package/dist/index.mjs +1 -1
- package/package.json +30 -4
package/README.md
CHANGED
|
@@ -1,28 +1,207 @@
|
|
|
1
1
|
# @nexussdk/flags
|
|
2
2
|
|
|
3
|
-
Ultra-lightweight feature flags and remote config client SDK for browsers and edge runtimes (<8KB gzipped).
|
|
3
|
+
> Ultra-lightweight, production-grade feature flags and remote config client SDK for browsers and edge runtimes with MurmurHash3 bucketing, ABAC rule evaluation, real-time SSE hot-swapping, and zero-infra local dev server (< 8KB gzipped).
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@nexussdk/flags)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://bundlephobia.com)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- **Deterministic Rollout**: Pure TypeScript MurmurHash3 32-bit algorithm guarantees deterministic 0–100% percentage bucketing matching server-side evaluation with zero network round-trips.
|
|
14
|
+
- **ABAC Rule Engine**: Full attribute-based access control engine supporting string, number, array (`IN`, `NOT_IN`, `CONTAINS`, `STARTS_WITH`, `ENDS_WITH`), comparison operators (`GREATER_THAN`, `LESS_THAN`), and semantic versioning (`SEMVER_GTE`, `SEMVER_LTE`).
|
|
15
|
+
- **Real-Time Streaming (SSE)**: Built-in `SSEManager` with singleton connection pooling, exponential backoff reconnects, and instant `FLAG_UPDATE` / `FLAG_DELETE` live sync.
|
|
16
|
+
- **Offline-First & Bootstrap**: Instant 0ms boot via `bootstrap` options (SSR pre-evaluation, local JSON file, or boolean dictionary) with background revalidation.
|
|
17
|
+
- **Cross-Tab Synchronization**: In-memory cache backed by optional `localStorage` and `BroadcastChannel` for instant cross-tab state consistency.
|
|
18
|
+
- **Built-in Local Dev Server & GUI**: `nexus-flags-dev` CLI provides a zero-dependency local server with single-file web dashboard, JSON file persistence (`nexus-flags.json`), and live SSE broadcasting.
|
|
7
19
|
|
|
8
20
|
---
|
|
9
21
|
|
|
10
22
|
## Installation
|
|
11
23
|
|
|
12
24
|
```bash
|
|
13
|
-
npm install @nexussdk/flags
|
|
14
|
-
# or
|
|
15
25
|
pnpm add @nexussdk/flags
|
|
26
|
+
# or
|
|
27
|
+
npm install @nexussdk/flags
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
*(If using React or Vue, install `@nexussdk/sdk` instead for built-in hooks like `useFeatureFlag` and `useVariant`).*
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Quickstart (Vanilla JS / TypeScript)
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { NexusFlagsClient } from '@nexussdk/flags';
|
|
38
|
+
|
|
39
|
+
// 1. Initialize client
|
|
40
|
+
const flags = new NexusFlagsClient({
|
|
41
|
+
apiKey: 'pk_live_your_api_key',
|
|
42
|
+
baseUrl: 'https://api.nexus.dev',
|
|
43
|
+
user: {
|
|
44
|
+
id: 'usr_4829',
|
|
45
|
+
country: 'VN',
|
|
46
|
+
plan: 'enterprise',
|
|
47
|
+
appVersion: '2.4.0',
|
|
48
|
+
},
|
|
49
|
+
realtime: true, // Enable SSE live streaming
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// 2. Synchronous evaluation (0ms from cache / bootstrap)
|
|
53
|
+
if (flags.isEnabled('new_checkout_flow', false)) {
|
|
54
|
+
mountNewCheckout();
|
|
55
|
+
} else {
|
|
56
|
+
mountLegacyCheckout();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 3. Dynamic variant configurations
|
|
60
|
+
const discountRate = flags.getVariant<number>('promo_banner_v2', 'discount_rate', 0);
|
|
61
|
+
const layoutTheme = flags.getVariant<string>('checkout_v2', 'theme', 'standard');
|
|
62
|
+
|
|
63
|
+
// 4. Listen for realtime hot-swap updates
|
|
64
|
+
const unsubscribe = flags.onFlagChange('new_checkout_flow', (result) => {
|
|
65
|
+
console.log('Flag updated in realtime:', result.enabled, result.reason);
|
|
66
|
+
if (result.enabled) {
|
|
67
|
+
mountNewCheckout();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// 5. Update user identity (e.g. after login)
|
|
72
|
+
await flags.identify({
|
|
73
|
+
id: 'usr_9981',
|
|
74
|
+
country: 'SG',
|
|
75
|
+
plan: 'pro',
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// 6. Reset user on logout
|
|
79
|
+
flags.reset();
|
|
80
|
+
|
|
81
|
+
// 7. Cleanup on unmount
|
|
82
|
+
unsubscribe();
|
|
83
|
+
flags.destroy();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Configuration Options (`NexusFlagsOptions`)
|
|
89
|
+
|
|
90
|
+
| Option | Type | Default | Description |
|
|
91
|
+
| :--- | :--- | :--- | :--- |
|
|
92
|
+
| `apiKey` | `string` | Env | Public API key (`pk_live_...` or `nxs_dev_...`) |
|
|
93
|
+
| `baseUrl` | `string` | `https://api.nexus.dev` | Ingestion endpoint URL |
|
|
94
|
+
| `user` | `UserContext` | Anonymous UUID | Initial user identity for ABAC rules and rollout bucketing |
|
|
95
|
+
| `bootstrap` | `Record<string, ...>` | `undefined` | Pre-hydrated flags for 0ms SSR boot or offline JSON mode |
|
|
96
|
+
| `realtime` | `boolean` | `true` | Enables Server-Sent Events (SSE) stream subscription |
|
|
97
|
+
| `timeoutMs` | `number` | `3000` | Network timeout for background evaluation refresh |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Offline & Bootstrap Mode (Local JSON)
|
|
102
|
+
|
|
103
|
+
For small projects or offline development, you can completely bypass backend servers by bootstrapping flags from a local JSON file:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import localFlags from './nexus-flags.json';
|
|
107
|
+
|
|
108
|
+
const flags = new NexusFlagsClient({
|
|
109
|
+
bootstrap: localFlags,
|
|
110
|
+
realtime: false, // Optional: disable network calls completely
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Ready immediately without any network calls
|
|
114
|
+
const isDarkMode = flags.isEnabled('dark_mode', false);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The `bootstrap` parameter accepts:
|
|
118
|
+
- Simple boolean flags: `{ dark_mode: true, beta_ui: false }`
|
|
119
|
+
- Standard `nexus-flags.json` objects created by the dev server
|
|
120
|
+
- Full `FlagEvaluationResult` maps generated from SSR
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Local Dev Server (`nexus-flags-dev`)
|
|
125
|
+
|
|
126
|
+
The `@nexussdk/flags` package includes a standalone local flag management CLI with an embedded Web GUI dashboard:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Start local flag management server
|
|
130
|
+
npx nexus-flags-dev
|
|
131
|
+
# or in this monorepo
|
|
132
|
+
pnpm --filter @nexussdk/flags flags-server
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### CLI Options
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
nexus-flags-dev [options]
|
|
139
|
+
|
|
140
|
+
Options:
|
|
141
|
+
-p, --port <number> Port to listen on (default: 4568)
|
|
142
|
+
--host <string> Host interface to bind (default: localhost)
|
|
143
|
+
-f, --file <path> Path to JSON flags file (default: ./nexus-flags.json)
|
|
144
|
+
-h, --help Show help message
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Endpoints
|
|
148
|
+
|
|
149
|
+
| Method | Endpoint | Description |
|
|
150
|
+
| :--- | :--- | :--- |
|
|
151
|
+
| `GET` | `/` or `/gui` | Interactive Web GUI Dashboard |
|
|
152
|
+
| `GET` | `/health` | Health status and connected clients count |
|
|
153
|
+
| `GET` | `/api/v1/flags` | List all flags (JSON) |
|
|
154
|
+
| `POST` | `/api/v1/flags` | Create a new flag |
|
|
155
|
+
| `GET` | `/api/v1/flags/:key` | Retrieve a single flag definition |
|
|
156
|
+
| `PATCH` | `/api/v1/flags/:key` | Update flag properties, rollout %, or variants |
|
|
157
|
+
| `POST` | `/api/v1/flags/:key/toggle` | Toggle enabled switch & broadcast to clients |
|
|
158
|
+
| `DELETE` | `/api/v1/flags/:key` | Delete flag & broadcast deletion |
|
|
159
|
+
| `GET` | `/api/v1/flags/stream` | Real-time SSE stream for SDK live hot-swap |
|
|
160
|
+
| `GET` | `/api/v1/flags/eval` | Evaluation snapshot for SDK background refresh |
|
|
161
|
+
| `GET` | `/api/v1/flags/bootstrap` | Pre-load snapshot for SSR bootstrap |
|
|
162
|
+
|
|
163
|
+
### Connecting SDK to Local Dev Server
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
const client = new NexusFlagsClient({
|
|
167
|
+
apiKey: 'nxs_dev_local',
|
|
168
|
+
baseUrl: 'http://localhost:4568',
|
|
169
|
+
realtime: true, // Whenever you toggle a flag in the GUI, your app updates instantly!
|
|
170
|
+
});
|
|
16
171
|
```
|
|
17
172
|
|
|
18
173
|
---
|
|
19
174
|
|
|
20
|
-
##
|
|
175
|
+
## Programmatic Dev Server Export
|
|
176
|
+
|
|
177
|
+
You can also embed the flags dev server programmatically in your test harness or Vite dev server:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { startFlagsDevServer } from '@nexussdk/flags/dev-server';
|
|
181
|
+
|
|
182
|
+
const devServer = await startFlagsDevServer({
|
|
183
|
+
port: 4568,
|
|
184
|
+
flagsFile: './test-flags.json',
|
|
185
|
+
seed: true,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Later in teardown:
|
|
189
|
+
await devServer.close();
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Framework Compatibility Matrix
|
|
195
|
+
|
|
196
|
+
`@nexussdk/flags` is completely framework-agnostic with zero runtime dependencies. It supports modern and legacy frontends:
|
|
21
197
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
198
|
+
| Framework | Supported Versions | Paradigm | Documentation |
|
|
199
|
+
| :--- | :--- | :--- | :--- |
|
|
200
|
+
| **React / Next.js** | React 16.8 – 19 / Next.js 13 – 16 | Server Components, Hooks, Context | [React Integration Guide](https://nexus.dev/sdk-flags/react-integration/) |
|
|
201
|
+
| **Vue / Nuxt** | Vue 2.7 & 3.x / Nuxt 3 & 4 | Composition API, `<script setup>`, SSR | [Vue Integration Guide](https://nexus.dev/sdk-flags/frameworks/vue/) |
|
|
202
|
+
| **Angular** | Angular 14 – 19+ / AngularJS | Signals (`@if`), Standalone, RxJS | [Angular Integration Guide](https://nexus.dev/sdk-flags/frameworks/angular/) |
|
|
203
|
+
| **Svelte / SvelteKit** | Svelte 3 – 5 / SvelteKit 1 & 2 | Runes (`$state`), Stores (`writable`) | [Svelte Integration Guide](https://nexus.dev/sdk-flags/frameworks/svelte/) |
|
|
204
|
+
| **Vanilla JS / Node.js** | Any ES2022+ runtime (Solid, Qwik, Lit) | Direct Class instance | [Vanilla JS Guide](https://nexus.dev/sdk-flags/frameworks/vanilla/) |
|
|
26
205
|
|
|
27
206
|
---
|
|
28
207
|
|