juice_analytics 0.1.0
juice_analytics: ^0.1.0 copied to clipboard
Event and screen tracking as a Juice bloc, with a consent gate and a fan-out sink seam.
juice_analytics #
Event and screen tracking as a Juice bloc — fanned out to one or more sinks, behind a consent gate.
What it owns #
Consent state and tracking bookkeeping. It does not own a vendor SDK — each
destination is an AnalyticsSink adapter (Firebase, Mixpanel, Segment, PostHog).
Install #
dependencies:
juice_analytics: ^0.1.0
Use #
final analytics = AnalyticsBloc.withConfig(AnalyticsConfig(
sinks: [
MyFirebaseSink(),
if (kDebugMode) ConsoleAnalyticsSink(),
],
initiallyEnabled: false, // require consent first
));
analytics.setConsent(true);
analytics.log('checkout_started', {'cart': 3});
analytics.screen('Cart');
analytics.setUser('u_123', {'plan': 'pro'});
Fan-out + isolation #
Every call fans out to all sinks; a sink that throws is isolated so it can't break tracking for the others.
Consent-first (privacy) #
When consent is off, events are dropped and counted — never buffered. So granting consent later never flushes a backlog of pre-consent events.
analytics.setConsent(false); // events now drop (state.droppedCount climbs)
setUser still records the id in state for your UI, but only forwards identity
to sinks with consent.
Writing a sink #
class MyFirebaseSink implements AnalyticsSink {
@override
Future<void> logEvent(String name, Map<String, Object?> params) =>
FirebaseAnalytics.instance.logEvent(name: name, parameters: params.cast());
@override
Future<void> setScreen(String name) =>
FirebaseAnalytics.instance.logScreenView(screenName: name);
// setUser / flush / dispose…
}
State #
| Field | Meaning |
|---|---|
enabled |
consent granted |
userId / screenName |
current identity / screen |
eventCount |
events forwarded this session |
droppedCount |
events dropped for lack of consent |
Rebuild groups: analytics:status, analytics:screen.
License #
MIT License — see LICENSE.