@plinthjs/pennant
v0.1.0
Published
Mason feature flags (the Laravel Pennant equivalent).
Maintainers
Readme
@plinthjs/pennant
Mason feature flags — the Laravel Pennant equivalent.
Define a feature whose value depends on an optional scope (a user, a team, a request — anything).
Resolved values are cached per (feature, scope), so each resolver runs once per scope.
import { FeatureManager } from '@plinthjs/pennant'
const feature = new FeatureManager()
// A simple on/off flag, resolved per scope.
feature.define('new-api', (user) => (user as { id: number }).id % 2 === 0)
// A richer "variant" value — `value()` surfaces it, `active()` coerces to truthiness.
feature.define('checkout-button', () => 'green')
const alice = { id: 2 }
await feature.active('new-api', alice) // => true
await feature.inactive('new-api', { id: 1 }) // => true
await feature.value('checkout-button', alice) // => 'green'
// Force a value regardless of the resolver.
feature.activate('new-api', { id: 1 }) // forced on
feature.deactivate('new-api', alice) // forced off
feature.forget('new-api', alice) // drop the cached/forced value — next read re-runs the resolver
feature.flushCache() // drop every cached value
// Bundle checks across features.
await feature.allAreActive(['new-api', 'checkout-button'], alice)
await feature.someAreActive(['new-api', 'checkout-button'], alice)
// A scope-bound accessor so you stop repeating the scope.
const forAlice = feature.for(alice)
await forAlice.active('new-api')
await forAlice.value('checkout-button')Scope serialization
The cache key for a scope is computed by a serializer. The default handles:
undefined/null— the shared global/null scope.- primitives (
string/number/boolean/bigint) — keyed bytype:value. - objects exposing
featureScopeIdorid— keyed by that identifier. - anything else — keyed by
JSON.stringify.
Pass your own via new FeatureManager({ serializer }).
Determinism
Pennant never reads the wall clock; caching is keyed purely on the serialized scope. Resolvers may
be sync or async — active/value/etc. always return a Promise.
