Private by construction
There is no I/O in the library. No network, storage, DOM, timers or globals. Nothing can leave the device because nothing in the code could send it.
A tiny, zero-dependency, pure-functional intent engine. Feed it the events your app already has; it tells you when a user is likely to upgrade, churn, get stuck or buy, with enough confidence to act, and shows its reasons.
Install with npm install oracular, then:
import { createState, markRevealed, observe, shouldReveal } from 'oracular';
let state = createState({
episodeTimeout: 30 * 60 * 1000, // 30 idle minutes end a session
intents: {
upgrade: {
prior: 0.05, priorStrength: 10, halfLife: 7 * 24 * 60 * 60 * 1000, // one week, in ms
signals: { 'pricing.viewed': 3, 'limit.hit': 2, 'export.clicked': 1 },
outcome: 'upgrade.completed',
},
},
});
state = observe(state, { name: 'pricing.viewed', at: Date.now() });
if (shouldReveal(state, 'upgrade', Date.now())) {
state = markRevealed(state, 'upgrade', Date.now()); // ...then show your offer
}With these numbers the offer fires after roughly six strong signals inside a week (p must clear 0.5 with a 90% lower bound); lower priorStrength or raise the weights to fire sooner. The block above is the same file the test suite runs, so it cannot rot.
Next: read the guide, browse the API reference, or play with the engine in your browser.