noibu-feature-flag
v0.2.0
Published
Noibu Feature Flag provider for web.
Readme
noibu-feature-flag
Standalone Noibu Feature Flag package for browser apps, based on OpenFeature Web SDK and GO Feature Flag web provider.
Install
npm install noibu-feature-flagUsage
import {
NoibuFeatureFlag,
NoibuFeatureFlagProvider,
NoibuProviderEvents,
type NoibuEvaluationContext
} from "noibu-feature-flag";
const context: NoibuEvaluationContext = {
targetingKey: "user-id",
// Custom attributes are top-level context fields (referenced by targeting
// rules by name, e.g. `plan`), not nested under an `attributes` key.
plan: "pro"
};
const provider = new NoibuFeatureFlagProvider({
endpoint: "https://your-feature-flag-endpoint/",
apiKey: "your-api-key",
maxRetries: 5,
dataFlushInterval: 5 * 60 * 1000,
apiTimeout: 1000
});
await NoibuFeatureFlag.setContext(context);
NoibuFeatureFlag.setProvider(provider);
const client = NoibuFeatureFlag.getClient("www.example.com");
client.addHandler(NoibuProviderEvents.Ready, () => {
console.log(client.getBooleanValue("my-flag", false));
});Automatic targeting key from the Noibu browser id
When setProvider initializes with no targetingKey in the context, the provider
resolves a browser id in the background and sets it on the global context. The
browser id is constant forever, resolved in priority order:
- live
NOIBUJS.noibuBrowserID(); - the localStorage caches (
n_browser_datafrom Noibu JS, orn_ff_browser_idfrom a previous fallback); - the
noibuSDKReadyevent, waited on for up to 1 second; - failing all of those, NOIBUJS is assumed broken: a UUID is generated, persisted
to
n_ff_browser_idso later visits reuse it, and a warning is logged (such exposures may not join to Noibu sessions).
This never delays provider readiness; flags re-evaluate once the id arrives. An
explicit targetingKey — in the initial context or set while waiting — always wins
and is never overwritten.
Building the context explicitly
To guarantee the very first evaluation is already keyed to the browser id (no
anonymous exposures before the id resolves), build the context up front with
buildNoibuContext before registering the provider. An explicit targetingKey
always wins, and if no browser id is available the context is returned unchanged.
import { buildNoibuContext, NoibuFeatureFlag } from "noibu-feature-flag";
// targetingKey defaults to NOIBUJS.noibuBrowserID() (awaits the Noibu JS SDK if needed).
// Custom attributes are top-level fields, not nested under `attributes`.
await NoibuFeatureFlag.setContext(await buildNoibuContext({ plan: "pro" }));
// ...or pass your own key (e.g. the console userId regime) — it is preserved as-is
await NoibuFeatureFlag.setContext(await buildNoibuContext({ targetingKey: "user-id" }));Collector metadata
Every data-collector flush sends a meta object:
{
"provider": "web",
"openfeature": true,
"browserId": "fb50a4f5-a785-4214-ab00-d34a15e154f5",
"domain": "console.noibu.com",
"sessionId": "019f6702-8298-7db2-930d-24cab496ccb6"
}The ids are resolved lazily at collect time (each flush), not at load: domain
from window.location.hostname; browserId per the priority order above;
sessionId from live NOIBUJS.sessionId(), else the n_session_id localStorage
cache (honoring its expiry), else null. Values passed via the exporterMetadata
option always win and extra custom keys are forwarded as-is.
Scripts
npm run buildbuilds ESM/CJS outputs and type declarations intodist.npm run lintruns ESLint forsrc.
