westyx/nexus. All read methods (getConfig, getSecret, getFlag, findFlag, etc.) are non-blocking - they hit the in-memory cache. Only NexusClient::create, sync, and evaluateAb make network calls - plus a targeted boolean evaluation through the OpenFeature provider, which calls evaluateAb for you.
Construction
NexusClient::create(NexusConfig $config, ?ClientInterface $http = null, ?RequestFactoryInterface $requestFactory = null, ?StreamFactoryInterface $streamFactory = null): self
Creates a client and runs a blocking initial sync. Returns the populated client. Throws on failure.
Throws:
NexusUnauthorizedException- initial sync returned 401NexusBillingException- initial sync returned 402NexusNotFoundException- initial sync returned 404
Configs
getConfig(string $key, mixed $default = null): mixed
Returns the resolved config value, or $default when the key is absent.
string, int, float, bool, array, or null. Cast or validate as needed.
getAllConfigs(): array
Returns a snapshot copy of every config key-value pair currently in the cache. The returned array is independent of the SDK’s internal storage - mutating it has no effect.
Feature flags
getFlag(string $key, bool $default = false): bool
Returns the is_active state of a flag, or $default when the key is absent.
is_active (combining is_enabled, starts_at, ends_at); the SDK never makes that call itself.
findFlag(string $key): ?bool
Returns the is_active state, or null when the flag is not defined.
getFlag() cannot express the difference between “the flag does not exist” and “it exists and is off” - both are false. Use this where the distinction matters:
FLAG_NOT_FOUND, and why an unknown key is never sent to evaluateAb(): the endpoint answers false for a key it does not know. getFlag() is expressed in terms of findFlag(), so the two cannot drift apart.
getAllFlags(): array
Returns a snapshot copy of every flag key-is_active pair in the cache. Keys are strings, values are booleans.
Secrets (secret key only)
getSecret(string $key): ?string
Returns the plaintext value of a text-type secret, or null when the key is absent or the secret is file-type.
null (does not throw) when:
- The key does not exist in the cache
- The secret has
type = 'file'- usegetSecretFilePathinstead
NexusPublicKeyException- client uses a public key
getSecretFilePath(string $key): ?string
Returns the temp-file path holding the value of a file-type secret, or null when the key is absent or the secret is text-type.
file-type secret on each sync, into a directory the client owns: created with a runtime-chosen random name and mode 0700, with the files inside created 0600 and O_EXCL. Nothing in the path is derived from the key name or the value, and two clients holding the same secret get independent files. Files are removed in __destruct, with a process-exit hook as a backstop.
Returns null when:
- The key does not exist in the cache
- The secret has
type = 'text'- usegetSecretinstead
NexusPublicKeyException- client uses a public key
Write API (secret key only)
setSecret(string $key, string $value, string $type = 'text'): void
Creates or updates a secret. $type must be 'text' or 'file'.
NexusPublicKeyException- client uses a public keyNexusUnauthorizedException- 401NexusBillingException- 402NexusNotFoundException- 404 (unknown service)NexusRateLimitedException- 429
deleteSecret(string $key): void
Deletes all versions of a secret.
NexusPublicKeyException- client uses a public keyNexusUnauthorizedException- 401NexusBillingException- 402NexusNotFoundException- 404 (secret or service not found)NexusRateLimitedException- 429
deleteSecretVersion(string $key, int $version): void
Deletes a specific version of a secret. Version numbers are 1-based integers matching the server’s version sequence.
NexusPublicKeyException- client uses a public keyNexusUnauthorizedException- 401NexusBillingException- 402NexusNotFoundException- 404 (secret, version, or service not found)NexusRateLimitedException- 429
A/B Testing
evaluateAb(array $keys, string $userId, array $attributes = []): array
Batch-evaluates feature flags through the AB Testing add-on against the supplied user context. Issues a single POST /v1/flags/evaluate-ab and returns the results map - flag key to evaluated boolean. Unlike getFlag, this method always performs a network call and does not consult the local cache.
Returns
array<string, bool>, carrying every key you asked about. At most 200 keys per call.
Attribute values must be strings. The endpoint binds them as a string-to-string map and cohort conditions compare them as strings, so a non-string value is rejected before the request is sent, with the attribute and the received type named. Nothing is stringified: no conversion is lossless, and a coerced value that then matches no cohort rule is harder to diagnose than one you were told about. A null value is treated as unset and dropped - kept as "" it could satisfy an eq "" rule.
Throws:
\InvalidArgumentException- an attribute value is not a string; no request is sentNexusAbAddonNotAvailableException- 403, the project does not have the AB Testing add-onNexusUnauthorizedException- 401NexusBillingException- 402NexusNotFoundException- 404NexusRateLimitedException- 429
SSE
connectStream(int $maxErrors = 3): void
Opens the SSE live-update connection. This method blocks indefinitely. It must only be called from CLI daemons and queue workers - never from FPM request handlers.
$maxErrorsconsecutive transport errors have occurred, at which point the SDK syncs on the configured TTL for a cooldown window and then attempts the stream again. The call itself does not return.
Sync
sync(): void
Forces an immediate sync, bypassing the TTL. ETag / If-None-Match is used automatically - a 304 resets the TTL without downloading data.
NexusUnauthorizedException- 401NexusBillingException- 402NexusNotFoundException- 404NexusRateLimitedException- 429NexusQuarantinedException- 429 quarantine body
Metadata
getKeyType(): string
Returns 'sk' or 'pk' based on the configured apiKey prefix. Returns '' when authentication is exclusively via WIF and no static apiKey is set.
