Latest release
v0.16.0What’s new in v0.16.0
- Breaking:
getSecret()removed, along withNexusPublicKeyErrorandNexusSecretNotFoundError. This SDK only ever holds a public key, and the backend never sends a secret to one, so the method could only ever throw. No change needed unless your code called it.
What’s new in v0.15.0
- A live stream that never connects is reported. When the client gives up before its first successful connection it says so once - through the logger you configured, or on
console.warnif you configured none. Reads keep succeeding on the TTL in that state, so without this a component looks healthy and its values simply stop changing. A connection lost after connecting is reported byuseNexusStreamStatus()instead. See SSE live updates. - The stream request carries only the API key and
Accept. Both are all the server needs, which is one fewer name a deployment’s CORS configuration has to allow.
What’s new in v0.14.0
- A flag or config bound in a template stays current while the live stream is unavailable. The TTL drives the refresh in that state, and the registration invalidates the composables when the snapshot reaches it. The request is still made by a read: an application that binds nothing makes no requests.
- An unchanged value does not fire a watcher. A composite config, the stream status and the sync timestamp keep their identity across a sync that changed nothing.
- A second registration on one application is refused with a directed error instead of replacing the first client and leaving it running unreachable.
- A composable called outside an injection context says so, and names
app.runWithContext(). useEvaluateAB()aborts its in-flight request when the application is torn down.- Breaking: the
vuepeer floor is now>=3.4.0- see Installation.
What’s new in v0.13.0
- A composite (object or array) resolution in the OpenFeature bridge carries an
integer beyond
Number.MAX_SAFE_INTEGERas its exact decimal string - at any depth, in objects and arrays alike, so the resolved value survivesJSON.stringify. Ordinary numbers are untouched, and the scalar number resolution still answersTYPE_MISMATCHfor the same value.
What’s new in v0.12.1
- The OpenFeature provider re-fetches targeted values only when the configuration
actually changed. The client reports every observable change, a stream state
transition included; the provider tells the two apart through
NexusClient.snapshotRevision, so a reconnect or a fall-back-to-polling costs no request and triggers no re-render. NexusClient.snapshotRevision- how many times the snapshot’s contents have been replaced.subscribealso fires for connection state and for the billing and quarantine flags, and this is what distinguishes a configuration change from those.- Closing the provider releases the identity it was holding, including from a refresh that had been requested but not yet sent.
- The bridge exports
NexusProviderOptions, so a caller can name the type of the options object it passes. - The bridge requires this SDK at
>=0.12.1, and its published type entry points resolve correctly from both ESM and CommonJS consumers.
What’s new in v0.12.0
- The OpenFeature provider resolves per user. An evaluation context carrying a
targetingKeyselects a per-user boolean evaluation through the Nexus AB Testing add-on, so rollout percentages and cohort rules apply. The request happens onsetContext, not on evaluation, so reading a flag stays synchronous; one round trip covers every flag in the snapshot. See OpenFeature. - The provider takes options:
loggerandaddonSuppressionMs, validated at construction. - The provider’s resolutions were corrected: an error resolution reports
DEFAULTorERRORrather thanSTATICbeside the error code, an unknown flag reportsFLAG_NOT_FOUND, every scalar resolution carries avariant, a number resolution no longer converts a boolean or a string into a number, and a JSONnullis reported as a missing value rather than as0. hasFlag(key)andgetFlagKeys()on the client - whether the service defines a flag at all, and every flag key in the snapshot.
Breaking changes
evaluateAB()anduseEvaluateAB()take string attribute values (Record<string, string>). The endpoint’s request type is string-to-string and answers anything else with a 400, so a call passing a number or a boolean was already failing; it is a compile error now.
What’s new in v0.11.0
This release rebuilds the client on a core shared with the Angular and React SDKs, so the three behave identically.createNexusPlugin()works from every component. The handle is registered duringinstall(), souseNexus()and the value composables resolve in a component that mounted before the initial sync finished. Values fall back to their defaults until the client lands, then update reactively;useNexusReady()reports when that has happened.- Composables are safe outside a component instance. They register no
listener of their own, so calling one from a Pinia store, from module scope, or
after the first
awaitin an asyncsetup()neither warns nor leaks. - Every request has a deadline, so a connection a middlebox stops answering cannot stop background refresh for the life of the page.
- A refresh is coalesced, and a slow response can never be applied over a newer one.
app.unmount()releases everything - the stream, every timer, every listener.- Large integers survive the decode. An integer above 2^53 arrives as a
bigintrather than rounded. - Configuration is validated at construction, naming the option, the reason and the value.
- Correct package resolution -
importresolves ESM,requireresolves CommonJS, each with matching types. - Tested on Vue 3.3 and 3.5.
Breaking changes
- A public key (
wxp_) is now required; any other key is rejected at construction. useSecret()has been removed - a browser client holds a public key, so it could only ever returnundefined.NEXUS_CLIENT_KEYis replaced byNEXUS_HANDLE.useNexusSyncedAt()returnsComputedRef<Date | null>.NexusLoggertakes structured fields:(message, fields?), with awarnlevel added.ttlMs: 0and an emptysseReconnectCooldownarray are rejected rather than coerced into a zero delay.
Where to start
- Installation - the registry, the token, the key
- Quick start - a working app and your first flag
- API reference - every composable and option
- Caching behaviour - when it refreshes, and what happens when the server pushes back
How it works
One bulkGET /v1/sync fills an in-memory snapshot. A live event stream pushes
changes as they happen; when it is unavailable the TTL drives polling instead,
and reads keep being served from the last snapshot throughout. A read never
blocks.
Public keys only
A browser SDK ships inside a bundle any visitor can read, so it accepts only a public key (wxp_). Public keys cannot read secrets, and the backend’s
Double-Gate check ties them to one service host. Secrets belong in a backend SDK.
