This is a Fusion plugin that captures events emitted from the client, sends them in batches to the server periodically, and allows the server to handle them.
It's useful for when you want to collect data about user actions or other metrics, and send them in bulk to the server to minimize the number of HTTP requests.
For convenience, universal-events
automatically flushes its queue on page unload.
yarn add fusion-plugin-universal-events
// main.js
import React from 'react';
import App from 'fusion-react';
import universalEvents from 'fusion-plugin-universal-events';
import Root from './components/root';
import analytics from './plugins/analytics';
export default function() {
const app = new App(<Root />);
const UniversalEvents = app.plugin(universalEvents);
const Analytics = app.plugin(analytics, {UniversalEvents});
return app;
}
// components/root.js
export default ({}, {universalEvents}) => {
function trackSignUp() {
universalEvents.emit('user-action', {
action: 'click',
target: 'sign up button',
});
}
return <button onClick={trackSignUp}>Sign up</button>;
}
// plugins/analytics.js
export default function({UniversalEvents}) => (ctx, next) => {
UniversalEvents.of(ctx).on('user-action', ({action, target}) => {
// logs `User did a click on sign up button` both in client and server
console.log(`User did a ${action} on ${target}!`);
if (__NODE__) {
// save data
}
});
return next();
}
It's possible to transform event data with a mapping function, for example to attach a timestamp to all actions of a type.
const events = UniversalEvents.of();
events.map('user-action', payload => {
return {...payload, time: new Date().getTime()};
});
events.on('user-action', payload => {
console.log(payload); // logs {type: 'click', time: someTimestamp}
});
events.emit('user-action', {type: 'click'});
Event mappers and handlers take an optional second parameter ctx
. For example:
events.on('type', (payload, ctx) => {
//...
})
This parameter will be present when events are emitted from the ctx
scoped EventsEmitter instance. For example:
const eventsWithoutCtx = EventEmitter.of();
(ctx, next) => {
const eventsWithCtx = EventEmitter.of(ctx);
}
*
is a special event type which denotes all events. This allows you to add a mapper or handler to all events. For example:
events.map('*', payload => {
//
});
universalEvents
- A plugin that creates a UniversalEvents class when passed to app.plugin
import App from 'fusion-react';
import universalEvents from 'fusion-plugin-universal-events';
const UniversalEvents = app.plugin(universalEvents);
const events = UniversalEvents.of(ctx)
Returns an event emitter
ctx: Object
- A memoization key
events.on(type, callback)
Registers a callback to be called when an event of a type is emitted. Note that the callback will not be called if the event is emitted before the callback is registered.
type: string
- Required. The type of event to listen oncallback: (mappedPayload: Object, ctx?) => void
- Required. Runs when an event of matching type occurs. Receives thepayload
after it has been transformed by mapper functions, as well an optional ctx object.
events.emit(type, payload)
type: string
- Required. The type of event to emitpayload: Object
- Optional. Data to be passed to event handlers
events.map(type, callback)
type: string
- Required. The type of event to listen oncallback: (payload: Object, ctx?) => Object
- Required. Runs when an event of matching type occurs. Should return a modifiedpayload
events.flush()
Flushes the data queue to the server immediately. Does not affect flush frequency
events.setFrequency(frequency)
Sets the frequency at which data is flushed to the server. Resets the interval timer.
frequency: number
- Required.
events.teardown()
Stops the interval timer, clears the data queue and prevents any further data from being flushed to the server.