react-i13n
Advanced tools
Comparing version 0.1.10 to 0.1.11
@@ -51,5 +51,6 @@ /** | ||
* @param {Object} payload payload | ||
* @param {Function} callback callback | ||
* @param {Function} resolve promise resolve callback | ||
* @param {Function} reject promise reject callback | ||
*/ | ||
EventsQueue.prototype.executeEvent = function executeEvent (eventName, payload, callback) { | ||
EventsQueue.prototype.executeEvent = function executeEvent (eventName, payload, resolve, reject) { | ||
var self = this; | ||
@@ -65,11 +66,11 @@ var eventLog = { | ||
self._plugin.eventHandlers[eventName].apply(self._plugin, [payload, function eventCallback() { | ||
self._callbackAndCheckQueue(callback); | ||
self._callbackAndCheckQueue(resolve); | ||
}]); | ||
} else { | ||
debug('Handler ' + eventName + ' is not found: ' + self._plugin.name, eventLog); | ||
self._callbackAndCheckQueue(callback); | ||
self._callbackAndCheckQueue(resolve); | ||
} | ||
} catch (e) { | ||
debug('Handler ' + eventName + ' throws error: ' + self._plugin.name, e); | ||
self._callbackAndCheckQueue(callback); | ||
self._callbackAndCheckQueue(reject); | ||
} | ||
@@ -76,0 +77,0 @@ }; |
@@ -10,7 +10,8 @@ /** | ||
var debug = debugLib('ReactI13n'); | ||
var async = require('async'); | ||
var EventsQueue = require('./EventsQueue'); | ||
var I13nNode = require('./I13nNode'); | ||
var Promise = require('promise'); | ||
var ENVIRONMENT = (typeof window !== 'undefined') ? 'client' : 'server'; | ||
var GLOBAL_OBJECT = ('client' === ENVIRONMENT) ? window : global; | ||
var DEFAULT_HANDLER_TIMEOUT = 1000; | ||
@@ -40,2 +41,3 @@ // export the debug lib in client side | ||
this._rootModelData = options.rootModelData || {}; | ||
this._handlerTimeout = options.handlerTimeout || DEFAULT_HANDLER_TIMEOUT; | ||
@@ -75,9 +77,19 @@ // set itself to the global object so that we can get it anywhere by the static function getInstance | ||
ReactI13n.prototype.execute = function execute (eventName, payload, callback) { | ||
var self = this; | ||
payload = payload || {}; | ||
payload.env = ENVIRONMENT; | ||
payload.i13nNode = payload.i13nNode || this.getRootI13nNode(); | ||
var handlers = this.getEventHandlers(eventName, payload); | ||
// async execute all handlers if plugins and then call callback function | ||
async.parallel(handlers, function asyncEnd() { | ||
var promiseHandlers = this.getEventHandlers(eventName, payload); | ||
promiseHandlers.push(new Promise(function handlerTimeoutPromise(resolve, reject) { | ||
setTimeout(function handlerTimeout () { | ||
debug('handler timeout in ' + self._handlerTimeout + 'ms.'); | ||
resolve(); | ||
}, self._handlerTimeout); | ||
})); | ||
// promised execute all handlers if plugins and then call callback function | ||
Promise.race(promiseHandlers).then(function promiseSuccess () { | ||
callback && callback(); | ||
}, function promiseFailed (e) { | ||
debug('execute event failed', e); | ||
callback && callback(); | ||
}); | ||
@@ -105,7 +117,7 @@ }; | ||
* @param {Object} payload payload object | ||
* @return {Array} the handlers | ||
* @return {Array} the promise handlers | ||
*/ | ||
ReactI13n.prototype.getEventHandlers = function getEventHandlers (eventName, payload) { | ||
var self = this; | ||
var handlers = []; | ||
var promiseHandlers = []; | ||
if (self._plugins) { | ||
@@ -117,9 +129,9 @@ Object.keys(self._plugins).forEach(function getEventHandler (pluginName) { | ||
if (eventHandler) { | ||
handlers.push(function executeEventHandler(asyncCallback) { | ||
eventsQueue.executeEvent(eventName, payload, asyncCallback); | ||
}); | ||
promiseHandlers.push(new Promise(function executeEventHandler(resolve, reject) { | ||
eventsQueue.executeEvent(eventName, payload, resolve, reject); | ||
})); | ||
} | ||
}); | ||
} | ||
return handlers; | ||
return promiseHandlers; | ||
}; | ||
@@ -166,3 +178,5 @@ | ||
this._rootModelData = options.rootModelData ? options.rootModelData : this._rootModelData; | ||
this._handlerTimeout = options.handlerTimeout ? options.handlerTimeout : this._handlerTimeout; | ||
}; | ||
module.exports = ReactI13n; |
## I13n Component | ||
If the component has the i13n functionalities, we will mirror an `I13nNode` in `I13nTree` for that component, we provide two ways for you to generate an `I13nComponent`. You can use following `props` to set what we want the `I13nComponetn` act like. | ||
If your component needs i13n functionality, we will mirror an `I13nNode` in `I13nTree` for that component, we provide two ways for you to generate an `I13nComponent`. You can use following `props` to set what we want the `I13nComponetn` act like. | ||
* `i13nModel` - the i13nModel data object or a dynamic function returns the data object. | ||
@@ -11,7 +12,8 @@ * `isLeafNode` - define if it's a leaf node or not, we will fire `created` event for every node when it's created, `isLeafNode` will help us to know if you want to do the action. e.g, you might only want to send out beacons to record links. | ||
### createI13nNode(component, options) | ||
The `high order function` which integrate `I13nMixin`, it return a compoment with all I13n functionalities. | ||
The `high order component` which integrates the `I13nMixin`, it will return a compoment with full I13n functionality. | ||
* `component` - can be a string for native tags e.g., `a`, `button` or a react component you create | ||
* `options` - options object, it would be the default `props` of that I13nNode, you can also pass options with `props` to overwrite it. | ||
For example, if you want to track the links, you will need to create anchor with `createI13nNode` and enable the click tracking. | ||
For example, if you want to enable link tracking, you will need to create an anchor with the `createI13nNode` and enable the click tracking. | ||
@@ -32,3 +34,3 @@ ```js | ||
### I13nMixin | ||
Everything is done by the `i13nMixin`, which means you can add the `I13nMixin` into the component directly to give the component i13n functionalities. | ||
Everything is done by the `i13nMixin`, which means you can add the `I13nMixin` into the component directly to give the component i13n functionality. | ||
@@ -35,0 +37,0 @@ ```js |
## I13nNode | ||
The `I13nNode` class used to create an `I13nTree`, you will need this if you are implementing a plugin, we provide APIs for you to build the functionalities you want with the plugin. | ||
The `I13nNode` class used to create an `I13nTree`. You will need this if you are implementing a plugin. | ||
@@ -4,0 +4,0 @@ ### Constructor(parentNode, model, isLeafNode, isViewportEnabled) |
### APIs | ||
* [setupI13n](./setupI13n.md) - higher order function for us to complete app level `react-i13n` setting | ||
* [createI13nNode](./createI13nNode.md) - higher order function for us to create `i13nNode` | ||
* [setupI13n](./setupI13n.md) - higher order component that wraps your application to setup `react-i13n` settings | ||
* [createI13nNode](./createI13nNode.md) - higher order component to create an [I13nNode](./I13nNode.md) | ||
* [I13nNode](./I13nNode.md) - class of I13nNode, you will need this to implement the plugin |
## setupI13n | ||
We provide `setupI13n` as a convenient `higher order function` to setup the ReactI13n, you will need to pass your `top level component`, `options`, and `plugins` into. It takes care of creating a `ReactI13n` instance and setup the plugins. Just use the function to create a component then render it. | ||
We provide `setupI13n` as a convenient [higher order function](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) to setup the ReactI13n, you will need to pass your `top level component`, `options`, and `plugins` into it. This takes care of creating a `ReactI13n` instance and setting up the plugins. | ||
* `Component` - the top level component. | ||
* `Component` - the top level application component. | ||
* `options` - the options passed into ReactI13n. | ||
@@ -10,6 +10,7 @@ * `options.rootModelData` - define the `i13nModel` data of the root. | ||
* `options.isViewportEnabled` - define if you want to enable the viewport checking. | ||
* `options.handlerTimeout` - define the timeout of the event handler, the event callback will be executed even if handlers don't finish in time, default to 1000ms. | ||
* `plugins` - plugins array that you defined according to the definition below. | ||
```js | ||
var React = require('react/addons'); | ||
var React = require('react'); | ||
var setupI13n = require('react-i13n').setupI13n; | ||
@@ -23,6 +24,8 @@ var someReactI13nPlugin = require('some-react-i13n-plugin'); | ||
var I13nDempApp = setupI13n(DemoApp, { | ||
rootModelData: {site: 'foo'}, // the default i13n model apply to the root | ||
isViewportEnabled: true | ||
rootModelData: {site: 'foo'}, // the default i13n model data to apply to all i13n nodes | ||
isViewportEnabled: true, | ||
handlerTimeout: 500 | ||
}, [someReactI13nPlugin]); | ||
// then you could use I13nDemoApp to render you app | ||
``` |
@@ -1,8 +0,11 @@ | ||
## Implement the plugin. | ||
A valid plugin must contains | ||
## Creating a plugin | ||
A valid plugin must contain: | ||
* `name` - the plugin name | ||
* `eventHandlers` - handlers functions for the events, typically in the eventHandler function we would send out a tracking beacon, now `react-i13n` has `click`, `created` and `enterViewport`, you can define the events you need and implement the handlers function, e.g., `pageview`. | ||
All the `eventHandlers` will receive a `payload` object and a `callback` function. By default in payload you will get: | ||
* `payload.I13nNode` - the I13n node related to the event, then you could use the APIs provided by [I13nNode](../api/I13nNode.md) to get the information you need. It's typically used for default events e.g., `click`, `created`, `enterViewport`. For custom events, if you don't pass `I13nNode`, it will default be the `root I13n Node`. | ||
All of the `eventHandlers` will receive a `payload` object and a `callback` function. By default, in payload you will get: | ||
* `payload.I13nNode` - the I13n node related to the event, then you could use the APIs provided by [I13nNode](../api/I13nNode.md) to get the information you need. It's typically used for default events e.g., `click`, `created`, `enterViewport`. For custom events, if you don't pass `I13nNode`, the default will be the root I13nNode. | ||
* `payload.env` - `server` or `client`, some events e.g., `pageview` will fire on both server and client side, you can define the prefer way you want to handle the beacon. | ||
@@ -13,4 +16,4 @@ | ||
// define the plugin | ||
var gaPlugin = { | ||
name: 'ga', | ||
var fooPlugin = { | ||
name: 'foo', | ||
eventHandlers: { | ||
@@ -17,0 +20,0 @@ click: function (payload, callback) { |
## Event System | ||
`react-i13n` communicate with `plugins` using it's own `event system`, which provides the ability for `react-i13n` to control and communicate with multiple plugin at the same time. It helps `react-i13n` to make | ||
`react-i13n` communicates with `plugins` using it's own `event system`. This provides the ability for `react-i13n` to control and communicate with multiple plugins at the same time. In other words, whenever you request plugins to take actions, you will need to fire the event instead of accessing the instrumentation library directly. | ||
In other words, whenever you request plugins to take actions, you will need to fire the event instead of accessing the instrumentation library directly. | ||
### Default Events | ||
By default, `react-i13n` will fire following events: | ||
* `click` - happens when user click a `I13nNode` with `clickHandler` | ||
By default, `react-i13n` will fire the following events: | ||
* `click` - happens when the user clicks a `I13nNode` component with a `clickHandler` | ||
* `created` - happens when the `I13nComponent` is created | ||
* `enterViewport` - happens when the `isViewportEnabled` is true and the node enter the viewport | ||
* `enterViewport` - happens when the `isViewportEnabled` is true and the node enters the viewport | ||
@@ -20,3 +18,3 @@ ### reactI13n.execute(eventName, payload, callback) | ||
```js | ||
var React = require('react/addons'); | ||
var React = require('react'); | ||
var ReactI13n = require('react-i13n').ReactI13n; | ||
@@ -27,3 +25,3 @@ var fooPlugin = { | ||
customEvent: function (payload, callback) { | ||
// handle the event here, typically you will use some beacon function to fire beacon | ||
// handle the event here, typically you will use some beacon function to fire the beacon | ||
callback(); | ||
@@ -37,3 +35,3 @@ } | ||
componentWillMount: function () { | ||
// whenever you define a event handler, you can fire a event for that. | ||
// whenever you define a event handler, you can fire an event for that. | ||
ReactI13n.getInstance().execute('customEvent', {payload}, function beaconCallback () { | ||
@@ -40,0 +38,0 @@ // do whatever after beaconing |
@@ -1,5 +0,9 @@ | ||
## Integrate with Components | ||
## Integrating with Components | ||
If you have a video player and you want to trace each link, you might need to have `onClick` for each links, like: | ||
This guide will show you how to take an existing component and modify it to leverage `react-i13n`. This assumes you already [setup your application](../api/setupI13n.md) and are leveraging a [plugin](./guides/createPlugins.md). | ||
### Existing component | ||
Say you have a video player component and you want to track each link, you might need to have `onClick` for each links, for example: | ||
```js | ||
@@ -10,3 +14,4 @@ var Player = React.createClass({ | ||
trackButton: function (category, action) { | ||
beacon(category, action); // some beaconing function, e.g., ga provide by analytics.js | ||
// assume "beacon" is some beaconing function | ||
beacon(category, action); | ||
}, | ||
@@ -34,6 +39,8 @@ trackExternalLink: function (category, action, url) { | ||
#### Replace with I13n Components | ||
### Replace with I13n Components | ||
For better approach of instrumentation, you might want to remove the `onClick` hook everywhere, once you [setup](../api/setupI13n.md) `react-i13n` and have a [plugin](./guides/createPlugins.md) to handle the click event, you can start to use [createI13nNode](../api/createI13nNode.md#createi13nnodecomponent-options) to create components and integrate them to do the same thing. | ||
A better approach might be to remove the `onClick` hooks everywhere and use the [createI13nNode](../api/createI13nNode.md) component to create i13n components to do the same thing. | ||
Note, that you can also leverage the [i13nMixin](../api/createI13nNode.md#i13nmixin) to enhance an existing component with i13n functionality. | ||
```js | ||
@@ -71,4 +78,6 @@ var createI13nNode = require('react-i13n').createI13nNode; | ||
Now it seems easier, and you will notice that you have to put `category: VideoPlayer` everywhere, which seems duplicated, now you can integrate the inherit architecture, i.e., creating a parent i13n node for them to define the `category`, here we use [createI13nNode](../api/createI13nNode.md#createi13nnodecomponent-options) to wrap `Player` as an `I13nNode`, then define `category: VideoPlayer` here. | ||
This is better, however, you will notice that you have to put `category: VideoPlayer` on each node, which is verbose and not very [DRY](http://en.wikipedia.org/wiki/Don%27t_repeat_yourself). Now lets integrate the i13n inherit architecture, which will create an i13n parent node for them to define the `category`. | ||
Below we use [createI13nNode](../api/createI13nNode.md) to wrap `Player` as an `I13nNode`, then define `category: VideoPlayer`. | ||
```js | ||
@@ -103,8 +112,11 @@ var createI13nNode = require('react-i13n').createI13nNode; | ||
// in some other component | ||
<Player i13nModel={{category: 'VideoPlayer'}}></Player> // the player component is not a i13nNode and you can pass i13nModel here, all the links inside will apply these model data | ||
<Player i13nModel={{category: 'VideoPlayer'}}></Player> | ||
``` | ||
The player component is now an i13nNode and you can pass i13nModel here, all the links inside will apply this model data. | ||
### Dynamic I13n Model | ||
If you need to pass video title as `label`, instead of static data, you will need to dynamically generate label value, here you can modify to pass `function` as `i13nModel`. | ||
If you need to pass video title as `label`, instead of static data, you will need to dynamically generate label value, here you can pass in a `function` as `i13nModel`. | ||
@@ -149,7 +161,8 @@ ```js | ||
### I13n Wrapper In Templates | ||
### I13n Wrapper in Components | ||
Sometimes you just want to group links in your template instead of creating a component with i13n functionalities, you can create a middle tag and pass `i13nModel` directly as following modification. So that you can easily group links with some shared i13n data definition. | ||
* Please not that since we integrate the feature of `parent-based context`, with `dev` env, react will generate warning like | ||
Sometimes you just want to group links in your template instead of creating a component with i13n functionalities, you can create a simple component and pass `i13nModel` data directly. This way, you can easily group links with some shared i13n data definition. | ||
* Please note that since we integrate the feature of `parent-based context`, with `dev` env, react will generate warning like | ||
```js | ||
@@ -159,3 +172,3 @@ Warning: owner-based and parent-based contexts differ (values: [object Object] vs [object Object]) for key (parentI13nNode) while mounting I13nAnchor (see: http://fb.me/react-context-by-parent) | ||
* This feature can only used after `react-0.13`, if you are using older version, you will have to create a component as above [example](#integrate-with-parent-nodes). | ||
* This feature can only be used after `react-0.13`, if you are using an older version, you will have to create the component as mentioned above [example](#integrate-with-parent-nodes). | ||
@@ -187,2 +200,4 @@ ```js | ||
}); | ||
// this will be used to group the i13n data without creating a i13nNode | ||
var I13nDiv = createI13nNode('div', { | ||
@@ -220,3 +235,3 @@ isLeafNode: false, | ||
For common usage, we define some components with specific setting, you can require them without generating them every time. These setting can be overwritten by `props`. | ||
For common usage, the following components are available, you can require them without generating them every time. These setting can be overwritten by `props`. | ||
@@ -223,0 +238,0 @@ | Component | isLeafNode | bindClickEvent | follow | |
### Guides | ||
* [create plugins](./createPlugins.md) - guideline about how to create a plugin. | ||
* [event system](./eventSystem.md) - introduce how we utilize the event system. | ||
* [integrate with components](./integrateWithComponents.md) - introduce how we manage i13n data, integrate with components and take the benefit of `react-i13n`. | ||
* [main ideas](./mainIdeas.md) - the ideas and the implementation details. | ||
* [Creating a Plugin](./createPlugins.md) - guideline about how to create a plugin. | ||
* [Event System](./eventSystem.md) - introduce how we utilize the event system. | ||
* [Integrating with Components](./integrateWithComponents.md) - a guide on how to manage i13n data, integrate with components and leverage `react-i13n`. |
{ | ||
"name": "react-i13n", | ||
"description": "react i13n", | ||
"version": "0.1.10", | ||
"version": "0.1.11", | ||
"main": "index.js", | ||
@@ -16,3 +16,2 @@ "repository": { | ||
"dependencies": { | ||
"async": "^0.9.0", | ||
"debug": "^2.1.3", | ||
@@ -22,2 +21,3 @@ "eventemitter3": "^0.1.6", | ||
"object-assign": "^2.0.0", | ||
"promise": "^7.0.1", | ||
"setimmediate": "^1.0.2" | ||
@@ -58,3 +58,3 @@ }, | ||
"peerDependencies": { | ||
"react": "<= 0.13.x" | ||
"react": "<0.14.0" | ||
}, | ||
@@ -73,3 +73,9 @@ "precommit": [ | ||
"node": true | ||
} | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "BSD", | ||
"url": "https://github.com/yahoo/react-i13n/blob/master/LICENSE.md" | ||
} | ||
] | ||
} |
@@ -5,32 +5,21 @@ # react-i13n | ||
`react-i13n` provides a performant and scalable approach to instrumentation. | ||
`react-i13n` provides a performant, scalable and pluggable approach to instrumenting your React application. | ||
In most cases, you will have to manually add the code to what you want to track, e.g., you have to hook `onClick` to the links you want to track. `react-i13n` provide a convenient approach for you to do the instrumentation, all you have to do is to define the data model you want to beacon out. | ||
Typically, you have to manually add instrumentation code throughout your application, e.g., hooking up `onClick` handlers to the links you want to track. `react-i13n` provides a simplified approach by letting you define the data model you want to track and handling the beaconing for you. | ||
Moreover, we provide a mechanism to build the `instrumentation tree`, typically you might have to manage the `instrumentation model data` you want and send out beacons separately, by using `react-i13n`, you have a better way to manage beacon data with an inheritance architecture, refer to [integrate with components](./docs/guides/integrateWithComponents.md) to see how do we get the benifit of `react-i13n`. | ||
`react-i13n` does this by building an [instrumentation tree](#i13n-tree) that mirrors your applications React component hierarchy. All you have to do it leverage our [React component or mixin](./docs/guides/integrateWithComponents.md) to denote which components should fire the tracking events. | ||
It's originated from [Rafael Martins](http://www.slideshare.net/RafaelMartins21/instrumentation-talk-39547608). More implement detail please refer to [Main Ideas](#main-ideas) section. | ||
## Features | ||
* Provides [createI13nNode](./docs/api/createI13nNode.md#createi13nnodecomponent-options) and [I13nMixin](./docs/api/createI13nNode.md#i13nmixin) to generate components as an easy way to track the links. | ||
* By integrating the tree architecture, you can get instrumentation data efficiently, and you can integrate the inherit architecture to manage them. | ||
* `react-i13n` is pluggable to integrate any data analytics library into the same tree architecture. All that is needed is to implement the plugin and the handler functions which integrate with the libraries transport functions. | ||
* `i13nModel` could be a plain object or a `dynamic function` with a proper `i13nModel` object return, which means you can dynamically change `i13nModel` data without causing re-render due to the `props` changes. | ||
* All the components we provide are harmony with both server side and client side, If you are using isomorphic framework to build your app, you could get some events e.g., `pageview` on both server and client side, which means you could select a prefer way to handle the event. | ||
* We integrate the viewport checking and set the status in each `I13nNode`, it could be used to know if you want to send out the data only when node is in viewport. | ||
* **i13n tree** - Automated [instrumentation tree](#i13n-tree) creation that mirrors your applications React component hierarchy. | ||
* **React integration** - Provides a [createI13nNode](./docs/api/createI13nNode.md#createi13nnodecomponent-options) component and [I13nMixin](./docs/api/createI13nNode.md#i13nmixin) that easily integrate with your application. | ||
* **Pluggable** - A pluggable interface lets you integrate any data analytics library (i.e. Google Analytics, Segment, etc). Take a look at the [available plugins](#available-plugins). | ||
* **Performant** - Tracking data (`i13nModel`) can be a plain JS object or custom function. This means you can [dynamically change tracking data](./docs/guides/integrateWithComponents.md#dynamic-i13n-model) without causing unnecessary re-renders. | ||
* **Adaptable** - If you are using an isomorphic framework (e.g. [Fluxible](http://fluxible.io)) to build your app, you can easily [change the tracking implementation](./docs/guides/createPlugins.md) on the server and client side. For example, to track page views, you can fire an http request on server and xhr request on the client. | ||
* **Optimizable** - We provide an option to enable viewport checking for each `I13nNode`. Which means that data will only be beaconed when the node is in the viewport. This reduces the network usage for the user and provides better tracking details. | ||
## Main Ideas | ||
`react-i13n` utilizes the life cycle events provided by `React` to build an i13n tree that mirrors the React component hierarchy. This approach optimizes for performance by reducing the need to scrape the DOM for data before beaconing. | ||
### I13n Tree | ||
* `react-i13n` build the `I13n Tree` with `context` and life cycle event `componentWillMount`, we can define the `i13nModel` data we need. Which means we don't need additional DOM manipulation when we want to get `i13nModel` values for sending out beacons for the link. | ||
### Inherit Architecture | ||
* We can define i13n data for each level, whenever we want to get the `i13nModel` for certain node, it traverses back to the root and merge all the `i13nModel` information in the path. Since the tree is already built and we don't need extra DOM access, it should be pretty cheap and efficient. | ||
## Install | ||
``` | ||
npm install react-i13n | ||
npm install react-i13n --save | ||
``` | ||
@@ -40,9 +29,9 @@ | ||
* Implement the [plugin](./docs/guides/createPlugins.md) for your preferred instrumentation mechanism. | ||
* Use [setupI13n](./docs/api/setupI13n.md) to create a top level component. | ||
* Choose the appropriate [plugin](#available-plugins). | ||
* Use the [setupI13n](./docs/api/setupI13n.md) utility to wrap your application component. | ||
* Define your instrumentation data and [integrate with your components](./docs/guides/integrateWithComponents.md) | ||
* Follow the [event system](./docs/guides/eventSystem.md) if you want to fire events manually. | ||
* (Optionally) follow the [event system](./docs/guides/eventSystem.md) if you want to fire events manually. | ||
```js | ||
var React = require('react/addons'); | ||
var React = require('react'); | ||
var ReactI13n = require('react-i13n').ReactI13n; | ||
@@ -53,2 +42,3 @@ var setupI13n = require('react-i13n').setupI13n; | ||
// create a i13n anchor for link tracking | ||
// or you can use the mixin to track an existing component | ||
var createI13nNode = require('react-i13n').createI13nNode; | ||
@@ -77,2 +67,3 @@ var I13nAnchor = createI13nNode('a', { | ||
}, [somePlugin]); | ||
// then you could use I13nDemoApp to render you app | ||
@@ -84,8 +75,20 @@ ``` | ||
## Test | ||
Or follow our guide and [create your own](./docs/api/createPlugins.md). | ||
## I13n Tree | ||
`react-i13n` builds the instrumentation tree by leveraging the undocumented React `context` feature and the `componentWillMount` life cycle event. Each component can define a `i13nModel` prop that defines the data it needs to track. This approach is more performant, as it means you do not need additional DOM manipulation when you want to collect the tracking data values for sending out beacons. | ||
Since the i13n data is defined at each level. Whenever you want to get the `i13nModel` for a certain node, `react-i13n` will traverse back up the tree to merge all the `i13nModel` information in the hierarchy. Since the tree is already built, you do not need extra DOM access, which is cheap and efficient. | ||
## Presentation | ||
Take a look at [Rafael Martins' slides](http://www.slideshare.net/RafaelMartins21/instrumentation-talk-39547608) from a recent React meetup to understand more. | ||
## Testing | ||
### Unit | ||
* `grunt unit` to run simply unit test | ||
* `grunt cover` to generate the coverage report | ||
* `grunt unit` to run unit tests | ||
* `grunt cover` to generate the istanbul coverage report | ||
@@ -100,1 +103,7 @@ ### Functional | ||
* `grunt functional` | ||
## License | ||
This software is free to use under the Yahoo Inc. BSD license. | ||
See the [LICENSE file][] for license text and copyright information. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
114119
39
2371
104
+ Addedpromise@^7.0.1
+ Addedasap@2.0.6(transitive)
+ Addedpromise@7.3.1(transitive)
- Removedasync@^0.9.0
- Removedasync@0.9.2(transitive)