Comparing version
@@ -71,27 +71,49 @@ 'use strict'; | ||
var EVENTS = { | ||
INITIALIZE: 'analyticsInit', // 'analyticsInit' | ||
INITIALIZE: 'analyticsInit', | ||
HANDLE_PARAMS: 'params', | ||
SET_CAMPAIGN: 'campaign', | ||
READY: 'ready', // 'analyticsReady' | ||
/* Integration actions */ | ||
REGISTER_INTEGRATION: 'integration_init', // 'integrationInit' | ||
INTEGRATION_LOADED: 'integration_ready', // 'integrationLoaded' | ||
INTEGRATION_FAILED: 'integration_failed', // 'integrationFailed' | ||
ENABLE_INTEGRATION: 'enable_integration', // 'integrationEnabled' | ||
DISABLE_INTEGRATION: 'disable_integration', // 'integrationDisabled' | ||
INTEGRATION_INIT: 'integrationInit', | ||
INTEGRATION_LOADED: 'integrationLoaded', | ||
INTEGRATION_FAILED: 'integrationFailed', | ||
INTEGRATION_LOADED_NAME: function INTEGRATION_LOADED_NAME(name) { | ||
return 'integrationLoaded:' + name; | ||
}, | ||
INTEGRATION_FAILED_NAME: function INTEGRATION_FAILED_NAME(name) { | ||
return 'integrationFailed:' + name; | ||
}, | ||
// Todo finish this event | ||
INTEGRATION_ENABLED: 'integrationEnabled', | ||
INTEGRATION_DISABLE: 'integrationDisabled', | ||
ENABLE_INTEGRATION: 'enableIntegration', | ||
DISABLE_INTEGRATION: 'disableIntegration', | ||
READY: 'analyticsReady', | ||
/* Page actions */ | ||
PAGE_START: 'page_init', // 'pageInit' | ||
PAGE: 'page', // 'page' | ||
PAGE_COMPLETE: 'page_complete', // 'pageCompleted' | ||
PAGE_ABORT: 'page_abort', // 'pageAborted' // TODO add this | ||
PAGE_INIT: 'pageInit', | ||
PAGE: 'page', | ||
PAGE_NAMESPACE: function PAGE_NAMESPACE(name) { | ||
return 'page:' + name; | ||
}, | ||
PAGE_COMPLETE: 'pageCompleted', | ||
PAGE_ABORT: 'pageAborted', | ||
PAGE_TIME_OUT: 'pageTimedOut', | ||
/* Track actions */ | ||
TRACK_START: 'track_init', // 'trackInit' | ||
TRACK: 'track', // 'track' | ||
TRACK_COMPLETE: 'track_complete', // 'trackCompleted' | ||
TRACK_ABORT: 'track_abort', // 'trackAborted' | ||
TRACK_INIT: 'trackInit', | ||
TRACK: 'track', | ||
TRACK_NAMESPACE: function TRACK_NAMESPACE(name) { | ||
return 'track:' + name; | ||
}, | ||
TRACK_COMPLETE: 'trackCompleted', | ||
TRACK_ABORT: 'trackAborted', | ||
TRACK_TIME_OUT: 'trackTimedOut', | ||
/* Identify actions */ | ||
IDENTIFY_START: 'identify_init', // 'identifyInit' | ||
IDENTIFY: 'identify', // 'identify' | ||
IDENTIFY_COMPLETE: 'identify_complete', // 'identifyCompleted' | ||
IDENTIFY_ABORTED: 'identify_abort' // 'identifyAborted' // TODO add this | ||
IDENTIFY_INIT: 'identifyInit', | ||
IDENTIFY: 'identify', | ||
IDENTIFY_NAMESPACE: function IDENTIFY_NAMESPACE(name) { | ||
return 'identify:' + name; | ||
}, | ||
IDENTIFY_COMPLETE: 'identifyCompleted', | ||
IDENTIFY_ABORTED: 'identifyAborted' // 'identifyAborted' // TODO add this | ||
}; | ||
@@ -140,6 +162,2 @@ | ||
} | ||
// why did I do this? | ||
// if (typeof eventName === 'string') { | ||
// data.eventName = eventName | ||
// } | ||
return data; | ||
@@ -175,5 +193,7 @@ } | ||
if (type === EVENTS.TRACK_START) { | ||
if (type === EVENTS.TRACK_INIT) { | ||
var dataObject = data && (typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object' ? data : {}; | ||
var cb = getCallback(data, options, callback); | ||
// format data payload | ||
var payload = formatPayload(eventName, data); | ||
var payload = formatPayload(eventName, dataObject); | ||
// setup data | ||
@@ -186,4 +206,8 @@ var dispatchData = { | ||
// if abort === true stop the rest | ||
};if (action.abort) { | ||
};if (action.abort || !eventName || typeof eventName !== 'string') { | ||
// Todo add reason why aborting happened | ||
store.dispatch(_extends({ type: EVENTS.TRACK_ABORT }, dispatchData)); | ||
if (!eventName) { | ||
console.log('Missing eventName'); | ||
} | ||
return next(action); | ||
@@ -193,2 +217,3 @@ } | ||
var trackCalls = getIntegrationWithMethod(getIntegrations(), 'track'); | ||
// No tracking middleware attached | ||
@@ -201,11 +226,8 @@ if (!trackCalls.length) { | ||
var trackCount = 0; | ||
var completed = []; | ||
var hasRan = false; | ||
/* Filter out disabled integrations */ | ||
trackCalls.filter(function (provider) { | ||
var integrations = options && options.integrations; | ||
var disabled = integrations && integrations[provider.NAMESPACE] === false; | ||
if (disabled) { | ||
console.log('ABORT TRACK>>>>>', provider.NAMESPACE, type); | ||
} | ||
var integrationsOpts = options && options.integrations; | ||
var disabled = integrationsOpts && integrationsOpts[provider.NAMESPACE] === false; | ||
return !disabled; | ||
@@ -221,11 +243,33 @@ /* Handle all .track calls */ | ||
var state = store.getState(); | ||
var _state$integrations$N = state.integrations[NAMESPACE], | ||
loaded = _state$integrations$N.loaded, | ||
enabled = _state$integrations$N.enabled; | ||
// enrich options | ||
var enrichedOptions = _extends({}, state, { options: options }); | ||
// get callback from args passed in | ||
var integrationLoaded = state.integrations[NAMESPACE].loaded; | ||
if (!integrationLoaded) { | ||
// Integration not enabled abort call | ||
if (!enabled) { | ||
// console.log('ABORT TRACK 2>>>>>', provider.NAMESPACE, type) | ||
trackCount = trackCount + 1; | ||
// all track calls complete | ||
if (trackCount === trackCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
trackCompleted(dispatchData, state, completed, store, cb); | ||
} | ||
return false; | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
if (timer > timeoutMax) { | ||
store.dispatch(_extends({}, dispatchData, { type: 'trackingTimeout' })); | ||
// TODO: save to queue | ||
// TODO send the event data with timestamp to `failedTrackCall` key? | ||
store.dispatch(_extends({}, dispatchData, { | ||
type: EVENTS.TRACK_TIME_OUT, | ||
integration: NAMESPACE | ||
})); | ||
// TODO: save to retry queue | ||
trackCompleted(dispatchData, state, completed, store, cb); | ||
return false; | ||
@@ -251,5 +295,6 @@ } | ||
store.dispatch(_extends({ | ||
type: 'track:' + NAMESPACE, | ||
integration: NAMESPACE | ||
type: EVENTS.TRACK_NAMESPACE(NAMESPACE) | ||
}, dispatchData)); | ||
completed = completed.concat(NAMESPACE); | ||
// increment success counter | ||
@@ -259,6 +304,4 @@ trackCount = trackCount + 1; | ||
if (trackCount === trackCalls.length) { | ||
var cb = getCallback(data, options, callback); | ||
if (cb) cb(state); | ||
// dispatch completion event for middlewares | ||
store.dispatch(_extends({ type: EVENTS.TRACK_COMPLETE }, dispatchData)); | ||
// Todo this logic is duplicated above in after abort | ||
trackCompleted(dispatchData, state, completed, store, cb); | ||
} | ||
@@ -275,2 +318,10 @@ }; | ||
function trackCompleted(dispatchData, state, completed, store, cb) { | ||
if (cb) { | ||
cb(state); | ||
} | ||
// dispatch completion event for middlewares | ||
store.dispatch(_extends({ type: EVENTS.TRACK_COMPLETE }, dispatchData, { integrations: completed })); | ||
} | ||
var getPageData = function getPageData() { | ||
@@ -327,3 +378,3 @@ var pageData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return { | ||
type: EVENTS.PAGE_START, | ||
type: EVENTS.PAGE_INIT, | ||
data: data, | ||
@@ -344,3 +395,4 @@ options: options, | ||
if (type === EVENTS.PAGE_START) { | ||
if (type === EVENTS.PAGE_INIT) { | ||
var cb = getCallback(data, options, callback); | ||
var pageCalls = getIntegrationWithMethod(getIntegrations(), 'page'); | ||
@@ -360,2 +412,3 @@ // No page middleware attached | ||
var count = 0; | ||
var completed = []; | ||
var hasRan = false; | ||
@@ -380,11 +433,25 @@ /* Handle all .page calls syncronously */ | ||
var state = store.getState(); | ||
var _state$integrations$N = state.integrations[NAMESPACE], | ||
loaded = _state$integrations$N.loaded, | ||
enabled = _state$integrations$N.enabled; | ||
var pageData = _extends({}, getPageData(), data); | ||
var enrichedOptions = _extends({}, state, { options: options }); | ||
if (!state.integrations[NAMESPACE].loaded) { | ||
console.log('try again page', NAMESPACE); | ||
if (!enabled) { | ||
console.log('ABORT Page viw >>>>>', NAMESPACE, type); | ||
count = count + 1; | ||
// all track calls complete | ||
if (pageCalls === pageCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
pageCompleted(store, completed, cb); | ||
} | ||
return false; | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
if (timer > timeoutMax) { | ||
store.dispatch({ | ||
type: 'pageTimeout', | ||
type: EVENTS.PAGE_TIME_OUT, | ||
name: NAMESPACE | ||
@@ -416,3 +483,3 @@ }); | ||
store.dispatch({ | ||
type: 'page:' + NAMESPACE, | ||
type: EVENTS.PAGE_NAMESPACE(NAMESPACE), | ||
data: pageData | ||
@@ -423,12 +490,7 @@ }); | ||
count = count + 1; | ||
completed = completed.concat(NAMESPACE); | ||
// all track calls complete | ||
if (count === pageCalls.length) { | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
type: EVENTS.PAGE_COMPLETE | ||
}); | ||
var cb = getCallback(data, options, callback); | ||
if (cb) { | ||
cb(store); | ||
} | ||
pageCompleted(store, completed, cb); | ||
} | ||
@@ -446,2 +508,35 @@ }; | ||
function pageCompleted(store, completed, cb) { | ||
// dispatch completion event for middlewares | ||
store.dispatch(_extends({ | ||
type: EVENTS.PAGE_COMPLETE | ||
}, { integrations: completed })); | ||
if (cb) { | ||
cb(store); | ||
} | ||
} | ||
/* run enable/disable integration callback if one is provided */ | ||
/* | ||
analytics.disableIntegration('vanilla', () => { | ||
console.log('my callback') | ||
}) | ||
*/ | ||
var integrationMiddleware = function integrationMiddleware(store) { | ||
return function (next) { | ||
return function (action) { | ||
var type = action.type, | ||
name = action.name, | ||
callback = action.callback; | ||
if (type === EVENTS.DISABLE_INTEGRATION || type === EVENTS.ENABLE_INTEGRATION) { | ||
if (callback) { | ||
callback(name); | ||
} | ||
} | ||
return next(action); | ||
}; | ||
}; | ||
}; | ||
function identifyMiddleware(getIntegrations) { | ||
@@ -457,4 +552,5 @@ return function (store) { | ||
if (type === EVENTS.IDENTIFY_START) { | ||
if (type === EVENTS.IDENTIFY_INIT) { | ||
var identifyCalls = getIntegrationWithMethod(getIntegrations(), 'identify'); | ||
var cb = getCallback(traits, options, callback); | ||
// No identify middleware attached | ||
@@ -471,5 +567,6 @@ if (!identifyCalls.length) { | ||
} | ||
var count = 0; | ||
var completed = []; | ||
var hasRan = false; | ||
// console.log('identifyCalls', identifyCalls) | ||
@@ -493,4 +590,19 @@ /* Filter out disabled integrations */ | ||
var state = store.getState(); | ||
var integrationLoaded = state.integrations[NAMESPACE].loaded; | ||
if (!integrationLoaded) { | ||
var _state$integrations$N = state.integrations[NAMESPACE], | ||
loaded = _state$integrations$N.loaded, | ||
enabled = _state$integrations$N.enabled; | ||
if (!enabled) { | ||
console.log('ABORT Identity viw >>>>>', NAMESPACE, type); | ||
count = count + 1; | ||
// all track calls complete | ||
if (identifyCalls === identifyCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
identifyCompleted(store, completed, cb); | ||
} | ||
return false; | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
@@ -526,14 +638,12 @@ if (timer > timeoutMax) { | ||
/* Run namespaced .identify calls */ | ||
store.dispatch({ type: 'identify:' + NAMESPACE }); | ||
store.dispatch({ | ||
type: EVENTS.IDENTIFY_NAMESPACE(NAMESPACE) | ||
}); | ||
// increment success counter | ||
count = count + 1; | ||
completed = completed.concat(NAMESPACE); | ||
// all identify calls complete | ||
if (count === identifyCalls.length) { | ||
var cb = getCallback(traits, options, callback); | ||
if (cb) cb(state); | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
type: EVENTS.IDENTIFY_COMPLETE | ||
}); | ||
identifyCompleted(store, completed, cb); | ||
} | ||
@@ -551,2 +661,12 @@ }; | ||
function identifyCompleted(store, completed, cb) { | ||
// dispatch completion event for middlewares | ||
store.dispatch(_extends({ | ||
type: EVENTS.IDENTIFY_COMPLETE | ||
}, { integrations: completed })); | ||
if (cb) { | ||
cb(store); | ||
} | ||
} | ||
/* | ||
@@ -609,3 +729,3 @@ The MIT License (MIT) | ||
// TODO fix version number. npm run publish:patch has wrong version | ||
version: "0.0.7" | ||
version: "0.0.8" | ||
}, | ||
@@ -652,4 +772,4 @@ campaign: {} | ||
switch (action.type) { | ||
case EVENTS.REGISTER_INTEGRATION: | ||
// console.log('REGISTER_INTEGRATION', action.name) | ||
case EVENTS.INTEGRATION_INIT: | ||
// console.log('INTEGRATION_INIT', action.name) | ||
// console.log('action.integration', action.integration) | ||
@@ -675,5 +795,7 @@ newState[action.name] = { | ||
case EVENTS.DISABLE_INTEGRATION: | ||
// console.log('DISABLE_INTEGRATION', action.name) | ||
newState[action.name] = _extends({}, state[action.name], { enabled: false }); | ||
return _extends({}, state, newState); | ||
case EVENTS.ENABLE_INTEGRATION: | ||
newState[action.name] = _extends({}, state[action.name], { enabled: true }); | ||
return _extends({}, state, newState); | ||
default: | ||
@@ -684,2 +806,18 @@ return state; | ||
var enableIntegration = function enableIntegration(name, callback) { | ||
return { | ||
type: EVENTS.ENABLE_INTEGRATION, | ||
name: name, | ||
callback: callback | ||
}; | ||
}; | ||
var disableIntegration = function disableIntegration(name, callback) { | ||
return { | ||
type: EVENTS.DISABLE_INTEGRATION, | ||
name: name, | ||
callback: callback | ||
}; | ||
}; | ||
// Track State | ||
@@ -703,3 +841,3 @@ var initialState$3 = { | ||
var l = !state.lastEvent ? data : state.event; | ||
console.log('>>>>>>>>>>>> state.lastEvent', state.lastEvent); | ||
// console.log('>>>>>>>>>>>> state.lastEvent', state.lastEvent) | ||
// TODO fix last event. 9/25 Still need to fix | ||
@@ -719,3 +857,3 @@ return _extends({}, state, { | ||
return { | ||
type: EVENTS.TRACK_START, | ||
type: EVENTS.TRACK_INIT, | ||
eventName: eventName, | ||
@@ -804,5 +942,4 @@ data: data, | ||
var identify = function identify(userId, traits, options, callback) { | ||
console.log('identify', userId, traits, options); | ||
return { | ||
type: EVENTS.IDENTIFY_START, | ||
type: EVENTS.IDENTIFY_INIT, | ||
userId: userId, | ||
@@ -815,2 +952,37 @@ traits: traits, | ||
function get$1(obj, path) { | ||
var pathArr = getPathSegments(path); | ||
for (var i = 0; i < pathArr.length; i++) { | ||
if (!Object.prototype.propertyIsEnumerable.call(obj, pathArr[i])) { | ||
return; | ||
} | ||
obj = obj[pathArr[i]]; | ||
if (obj === undefined || obj === null) { | ||
if (i !== pathArr.length - 1) { | ||
return; | ||
} | ||
break; | ||
} | ||
} | ||
return obj; | ||
} | ||
function getPathSegments(path) { | ||
var pathArr = path.split('.'); | ||
var parts = []; | ||
for (var i = 0; i < pathArr.length; i++) { | ||
var p = pathArr[i]; | ||
while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) { | ||
p = p.slice(0, -1) + '.'; | ||
p += pathArr[++i]; | ||
} | ||
parts.push(p); | ||
} | ||
return parts; | ||
} | ||
// Only way commonJS will work | ||
@@ -856,3 +1028,3 @@ module.exports = function (config) { | ||
// core middlewares | ||
initialize, identifyMiddleware(getIntegrations), trackMiddleware(getIntegrations), pageMiddleware(getIntegrations), dynamicMiddlewares]); | ||
initialize, identifyMiddleware(getIntegrations), trackMiddleware(getIntegrations), pageMiddleware(getIntegrations), integrationMiddleware, dynamicMiddlewares]); | ||
@@ -869,3 +1041,3 @@ // initial analytics state keys | ||
var composeEnhancers = redux.compose; | ||
if (analyticsUtils.inBrowser) { | ||
if (analyticsUtils.inBrowser && config.debug) { | ||
var withDevTools = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || redux.compose; | ||
@@ -896,3 +1068,3 @@ composeEnhancers = withDevTools; | ||
store.dispatch({ | ||
type: EVENTS.REGISTER_INTEGRATION, | ||
type: EVENTS.INTEGRATION_INIT, | ||
name: provider.NAMESPACE, | ||
@@ -923,7 +1095,3 @@ integration: provider | ||
{ | ||
console.log('intialize state', store.getState()); | ||
} | ||
return { | ||
var api = { | ||
// Get all state or state by key | ||
@@ -933,4 +1101,3 @@ getState: function getState(key) { | ||
if (key) { | ||
// TODO add dot notation and grab deeper values | ||
return state[key]; | ||
return get$1(state, key); | ||
} | ||
@@ -961,5 +1128,8 @@ return state; | ||
// get user data | ||
user: function user$$1() { | ||
// TODO add key to input and allow for pulling back specific values | ||
return store.getState().user; | ||
user: function user$$1(key) { | ||
var user$$1 = store.getState().user; | ||
if (key) { | ||
return get$1(user$$1, key); | ||
} | ||
return user$$1; | ||
}, | ||
@@ -991,7 +1161,2 @@ // analtyics.ready all integrations ready | ||
if (name === '*') { | ||
/* // store subscribe works but won't give current action context | ||
return store.subscribe(() => { | ||
callback(action, store) | ||
}) | ||
*/ | ||
var globalListener = function globalListener(store) { | ||
@@ -1031,5 +1196,11 @@ return function (next) { | ||
}, | ||
enableIntegration: function enableIntegration$$1(name, callback) { | ||
store.dispatch(enableIntegration(name, callback)); | ||
}, | ||
disableIntegration: function disableIntegration$$1(name, callback) { | ||
store.dispatch(disableIntegration(name, callback)); | ||
}, | ||
// TODO decide if this is good or bad ⊂◉‿◉つ. Exposing publicly could be bad | ||
addIntegration: function addIntegration(t) { | ||
// TODO if it stays, state loaded needs to be set. Re REGISTER_INTEGRATION above | ||
// TODO if it stays, state loaded needs to be set. Re INTEGRATION_INIT above | ||
// validate integration | ||
@@ -1044,3 +1215,3 @@ if ((typeof t === 'undefined' ? 'undefined' : _typeof(t)) === 'object') { | ||
store.dispatch({ | ||
type: EVENTS.REGISTER_INTEGRATION, | ||
type: EVENTS.INTEGRATION_INIT, | ||
name: t.NAMESPACE, | ||
@@ -1051,2 +1222,4 @@ integration: t | ||
}; | ||
return api; | ||
} | ||
@@ -1058,2 +1231,3 @@ | ||
var maxRetries = config.maxRetries; | ||
var NAMESPACE = provider.NAMESPACE; | ||
@@ -1063,6 +1237,6 @@ if (retryCount > maxRetries) { | ||
type: EVENTS.INTEGRATION_FAILED, | ||
name: provider.NAMESPACE | ||
name: NAMESPACE | ||
}); | ||
store.dispatch({ | ||
type: 'integration_failed:' + provider.NAMESPACE | ||
type: EVENTS.INTEGRATION_FAILED_NAME(NAMESPACE) | ||
}); | ||
@@ -1083,3 +1257,3 @@ return false; | ||
type: EVENTS.INTEGRATION_LOADED, | ||
name: provider.NAMESPACE | ||
name: NAMESPACE | ||
}); | ||
@@ -1089,3 +1263,3 @@ | ||
store.dispatch({ | ||
type: 'integration_ready:' + provider.NAMESPACE | ||
type: EVENTS.INTEGRATION_LOADED_NAME(NAMESPACE) | ||
}); | ||
@@ -1092,0 +1266,0 @@ |
@@ -69,27 +69,49 @@ import { compose, createStore, combineReducers, applyMiddleware } from 'redux'; | ||
var EVENTS = { | ||
INITIALIZE: 'analyticsInit', // 'analyticsInit' | ||
INITIALIZE: 'analyticsInit', | ||
HANDLE_PARAMS: 'params', | ||
SET_CAMPAIGN: 'campaign', | ||
READY: 'ready', // 'analyticsReady' | ||
/* Integration actions */ | ||
REGISTER_INTEGRATION: 'integration_init', // 'integrationInit' | ||
INTEGRATION_LOADED: 'integration_ready', // 'integrationLoaded' | ||
INTEGRATION_FAILED: 'integration_failed', // 'integrationFailed' | ||
ENABLE_INTEGRATION: 'enable_integration', // 'integrationEnabled' | ||
DISABLE_INTEGRATION: 'disable_integration', // 'integrationDisabled' | ||
INTEGRATION_INIT: 'integrationInit', | ||
INTEGRATION_LOADED: 'integrationLoaded', | ||
INTEGRATION_FAILED: 'integrationFailed', | ||
INTEGRATION_LOADED_NAME: function INTEGRATION_LOADED_NAME(name) { | ||
return 'integrationLoaded:' + name; | ||
}, | ||
INTEGRATION_FAILED_NAME: function INTEGRATION_FAILED_NAME(name) { | ||
return 'integrationFailed:' + name; | ||
}, | ||
// Todo finish this event | ||
INTEGRATION_ENABLED: 'integrationEnabled', | ||
INTEGRATION_DISABLE: 'integrationDisabled', | ||
ENABLE_INTEGRATION: 'enableIntegration', | ||
DISABLE_INTEGRATION: 'disableIntegration', | ||
READY: 'analyticsReady', | ||
/* Page actions */ | ||
PAGE_START: 'page_init', // 'pageInit' | ||
PAGE: 'page', // 'page' | ||
PAGE_COMPLETE: 'page_complete', // 'pageCompleted' | ||
PAGE_ABORT: 'page_abort', // 'pageAborted' // TODO add this | ||
PAGE_INIT: 'pageInit', | ||
PAGE: 'page', | ||
PAGE_NAMESPACE: function PAGE_NAMESPACE(name) { | ||
return 'page:' + name; | ||
}, | ||
PAGE_COMPLETE: 'pageCompleted', | ||
PAGE_ABORT: 'pageAborted', | ||
PAGE_TIME_OUT: 'pageTimedOut', | ||
/* Track actions */ | ||
TRACK_START: 'track_init', // 'trackInit' | ||
TRACK: 'track', // 'track' | ||
TRACK_COMPLETE: 'track_complete', // 'trackCompleted' | ||
TRACK_ABORT: 'track_abort', // 'trackAborted' | ||
TRACK_INIT: 'trackInit', | ||
TRACK: 'track', | ||
TRACK_NAMESPACE: function TRACK_NAMESPACE(name) { | ||
return 'track:' + name; | ||
}, | ||
TRACK_COMPLETE: 'trackCompleted', | ||
TRACK_ABORT: 'trackAborted', | ||
TRACK_TIME_OUT: 'trackTimedOut', | ||
/* Identify actions */ | ||
IDENTIFY_START: 'identify_init', // 'identifyInit' | ||
IDENTIFY: 'identify', // 'identify' | ||
IDENTIFY_COMPLETE: 'identify_complete', // 'identifyCompleted' | ||
IDENTIFY_ABORTED: 'identify_abort' // 'identifyAborted' // TODO add this | ||
IDENTIFY_INIT: 'identifyInit', | ||
IDENTIFY: 'identify', | ||
IDENTIFY_NAMESPACE: function IDENTIFY_NAMESPACE(name) { | ||
return 'identify:' + name; | ||
}, | ||
IDENTIFY_COMPLETE: 'identifyCompleted', | ||
IDENTIFY_ABORTED: 'identifyAborted' // 'identifyAborted' // TODO add this | ||
}; | ||
@@ -138,6 +160,2 @@ | ||
} | ||
// why did I do this? | ||
// if (typeof eventName === 'string') { | ||
// data.eventName = eventName | ||
// } | ||
return data; | ||
@@ -173,5 +191,7 @@ } | ||
if (type === EVENTS.TRACK_START) { | ||
if (type === EVENTS.TRACK_INIT) { | ||
var dataObject = data && (typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object' ? data : {}; | ||
var cb = getCallback(data, options, callback); | ||
// format data payload | ||
var payload = formatPayload(eventName, data); | ||
var payload = formatPayload(eventName, dataObject); | ||
// setup data | ||
@@ -184,4 +204,8 @@ var dispatchData = { | ||
// if abort === true stop the rest | ||
};if (action.abort) { | ||
};if (action.abort || !eventName || typeof eventName !== 'string') { | ||
// Todo add reason why aborting happened | ||
store.dispatch(_extends({ type: EVENTS.TRACK_ABORT }, dispatchData)); | ||
if (!eventName) { | ||
console.log('Missing eventName'); | ||
} | ||
return next(action); | ||
@@ -191,2 +215,3 @@ } | ||
var trackCalls = getIntegrationWithMethod(getIntegrations(), 'track'); | ||
// No tracking middleware attached | ||
@@ -199,11 +224,8 @@ if (!trackCalls.length) { | ||
var trackCount = 0; | ||
var completed = []; | ||
var hasRan = false; | ||
/* Filter out disabled integrations */ | ||
trackCalls.filter(function (provider) { | ||
var integrations = options && options.integrations; | ||
var disabled = integrations && integrations[provider.NAMESPACE] === false; | ||
if (disabled) { | ||
console.log('ABORT TRACK>>>>>', provider.NAMESPACE, type); | ||
} | ||
var integrationsOpts = options && options.integrations; | ||
var disabled = integrationsOpts && integrationsOpts[provider.NAMESPACE] === false; | ||
return !disabled; | ||
@@ -219,11 +241,33 @@ /* Handle all .track calls */ | ||
var state = store.getState(); | ||
var _state$integrations$N = state.integrations[NAMESPACE], | ||
loaded = _state$integrations$N.loaded, | ||
enabled = _state$integrations$N.enabled; | ||
// enrich options | ||
var enrichedOptions = _extends({}, state, { options: options }); | ||
// get callback from args passed in | ||
var integrationLoaded = state.integrations[NAMESPACE].loaded; | ||
if (!integrationLoaded) { | ||
// Integration not enabled abort call | ||
if (!enabled) { | ||
// console.log('ABORT TRACK 2>>>>>', provider.NAMESPACE, type) | ||
trackCount = trackCount + 1; | ||
// all track calls complete | ||
if (trackCount === trackCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
trackCompleted(dispatchData, state, completed, store, cb); | ||
} | ||
return false; | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
if (timer > timeoutMax) { | ||
store.dispatch(_extends({}, dispatchData, { type: 'trackingTimeout' })); | ||
// TODO: save to queue | ||
// TODO send the event data with timestamp to `failedTrackCall` key? | ||
store.dispatch(_extends({}, dispatchData, { | ||
type: EVENTS.TRACK_TIME_OUT, | ||
integration: NAMESPACE | ||
})); | ||
// TODO: save to retry queue | ||
trackCompleted(dispatchData, state, completed, store, cb); | ||
return false; | ||
@@ -249,5 +293,6 @@ } | ||
store.dispatch(_extends({ | ||
type: 'track:' + NAMESPACE, | ||
integration: NAMESPACE | ||
type: EVENTS.TRACK_NAMESPACE(NAMESPACE) | ||
}, dispatchData)); | ||
completed = completed.concat(NAMESPACE); | ||
// increment success counter | ||
@@ -257,6 +302,4 @@ trackCount = trackCount + 1; | ||
if (trackCount === trackCalls.length) { | ||
var cb = getCallback(data, options, callback); | ||
if (cb) cb(state); | ||
// dispatch completion event for middlewares | ||
store.dispatch(_extends({ type: EVENTS.TRACK_COMPLETE }, dispatchData)); | ||
// Todo this logic is duplicated above in after abort | ||
trackCompleted(dispatchData, state, completed, store, cb); | ||
} | ||
@@ -273,2 +316,10 @@ }; | ||
function trackCompleted(dispatchData, state, completed, store, cb) { | ||
if (cb) { | ||
cb(state); | ||
} | ||
// dispatch completion event for middlewares | ||
store.dispatch(_extends({ type: EVENTS.TRACK_COMPLETE }, dispatchData, { integrations: completed })); | ||
} | ||
var getPageData = function getPageData() { | ||
@@ -325,3 +376,3 @@ var pageData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return { | ||
type: EVENTS.PAGE_START, | ||
type: EVENTS.PAGE_INIT, | ||
data: data, | ||
@@ -342,3 +393,4 @@ options: options, | ||
if (type === EVENTS.PAGE_START) { | ||
if (type === EVENTS.PAGE_INIT) { | ||
var cb = getCallback(data, options, callback); | ||
var pageCalls = getIntegrationWithMethod(getIntegrations(), 'page'); | ||
@@ -358,2 +410,3 @@ // No page middleware attached | ||
var count = 0; | ||
var completed = []; | ||
var hasRan = false; | ||
@@ -378,11 +431,25 @@ /* Handle all .page calls syncronously */ | ||
var state = store.getState(); | ||
var _state$integrations$N = state.integrations[NAMESPACE], | ||
loaded = _state$integrations$N.loaded, | ||
enabled = _state$integrations$N.enabled; | ||
var pageData = _extends({}, getPageData(), data); | ||
var enrichedOptions = _extends({}, state, { options: options }); | ||
if (!state.integrations[NAMESPACE].loaded) { | ||
console.log('try again page', NAMESPACE); | ||
if (!enabled) { | ||
console.log('ABORT Page viw >>>>>', NAMESPACE, type); | ||
count = count + 1; | ||
// all track calls complete | ||
if (pageCalls === pageCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
pageCompleted(store, completed, cb); | ||
} | ||
return false; | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
if (timer > timeoutMax) { | ||
store.dispatch({ | ||
type: 'pageTimeout', | ||
type: EVENTS.PAGE_TIME_OUT, | ||
name: NAMESPACE | ||
@@ -414,3 +481,3 @@ }); | ||
store.dispatch({ | ||
type: 'page:' + NAMESPACE, | ||
type: EVENTS.PAGE_NAMESPACE(NAMESPACE), | ||
data: pageData | ||
@@ -421,12 +488,7 @@ }); | ||
count = count + 1; | ||
completed = completed.concat(NAMESPACE); | ||
// all track calls complete | ||
if (count === pageCalls.length) { | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
type: EVENTS.PAGE_COMPLETE | ||
}); | ||
var cb = getCallback(data, options, callback); | ||
if (cb) { | ||
cb(store); | ||
} | ||
pageCompleted(store, completed, cb); | ||
} | ||
@@ -444,2 +506,35 @@ }; | ||
function pageCompleted(store, completed, cb) { | ||
// dispatch completion event for middlewares | ||
store.dispatch(_extends({ | ||
type: EVENTS.PAGE_COMPLETE | ||
}, { integrations: completed })); | ||
if (cb) { | ||
cb(store); | ||
} | ||
} | ||
/* run enable/disable integration callback if one is provided */ | ||
/* | ||
analytics.disableIntegration('vanilla', () => { | ||
console.log('my callback') | ||
}) | ||
*/ | ||
var integrationMiddleware = function integrationMiddleware(store) { | ||
return function (next) { | ||
return function (action) { | ||
var type = action.type, | ||
name = action.name, | ||
callback = action.callback; | ||
if (type === EVENTS.DISABLE_INTEGRATION || type === EVENTS.ENABLE_INTEGRATION) { | ||
if (callback) { | ||
callback(name); | ||
} | ||
} | ||
return next(action); | ||
}; | ||
}; | ||
}; | ||
function identifyMiddleware(getIntegrations) { | ||
@@ -455,4 +550,5 @@ return function (store) { | ||
if (type === EVENTS.IDENTIFY_START) { | ||
if (type === EVENTS.IDENTIFY_INIT) { | ||
var identifyCalls = getIntegrationWithMethod(getIntegrations(), 'identify'); | ||
var cb = getCallback(traits, options, callback); | ||
// No identify middleware attached | ||
@@ -469,5 +565,6 @@ if (!identifyCalls.length) { | ||
} | ||
var count = 0; | ||
var completed = []; | ||
var hasRan = false; | ||
// console.log('identifyCalls', identifyCalls) | ||
@@ -491,4 +588,19 @@ /* Filter out disabled integrations */ | ||
var state = store.getState(); | ||
var integrationLoaded = state.integrations[NAMESPACE].loaded; | ||
if (!integrationLoaded) { | ||
var _state$integrations$N = state.integrations[NAMESPACE], | ||
loaded = _state$integrations$N.loaded, | ||
enabled = _state$integrations$N.enabled; | ||
if (!enabled) { | ||
console.log('ABORT Identity viw >>>>>', NAMESPACE, type); | ||
count = count + 1; | ||
// all track calls complete | ||
if (identifyCalls === identifyCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
identifyCompleted(store, completed, cb); | ||
} | ||
return false; | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
@@ -524,14 +636,12 @@ if (timer > timeoutMax) { | ||
/* Run namespaced .identify calls */ | ||
store.dispatch({ type: 'identify:' + NAMESPACE }); | ||
store.dispatch({ | ||
type: EVENTS.IDENTIFY_NAMESPACE(NAMESPACE) | ||
}); | ||
// increment success counter | ||
count = count + 1; | ||
completed = completed.concat(NAMESPACE); | ||
// all identify calls complete | ||
if (count === identifyCalls.length) { | ||
var cb = getCallback(traits, options, callback); | ||
if (cb) cb(state); | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
type: EVENTS.IDENTIFY_COMPLETE | ||
}); | ||
identifyCompleted(store, completed, cb); | ||
} | ||
@@ -549,2 +659,12 @@ }; | ||
function identifyCompleted(store, completed, cb) { | ||
// dispatch completion event for middlewares | ||
store.dispatch(_extends({ | ||
type: EVENTS.IDENTIFY_COMPLETE | ||
}, { integrations: completed })); | ||
if (cb) { | ||
cb(store); | ||
} | ||
} | ||
/* | ||
@@ -607,3 +727,3 @@ The MIT License (MIT) | ||
// TODO fix version number. npm run publish:patch has wrong version | ||
version: "0.0.7" | ||
version: "0.0.8" | ||
}, | ||
@@ -650,4 +770,4 @@ campaign: {} | ||
switch (action.type) { | ||
case EVENTS.REGISTER_INTEGRATION: | ||
// console.log('REGISTER_INTEGRATION', action.name) | ||
case EVENTS.INTEGRATION_INIT: | ||
// console.log('INTEGRATION_INIT', action.name) | ||
// console.log('action.integration', action.integration) | ||
@@ -673,5 +793,7 @@ newState[action.name] = { | ||
case EVENTS.DISABLE_INTEGRATION: | ||
// console.log('DISABLE_INTEGRATION', action.name) | ||
newState[action.name] = _extends({}, state[action.name], { enabled: false }); | ||
return _extends({}, state, newState); | ||
case EVENTS.ENABLE_INTEGRATION: | ||
newState[action.name] = _extends({}, state[action.name], { enabled: true }); | ||
return _extends({}, state, newState); | ||
default: | ||
@@ -682,2 +804,18 @@ return state; | ||
var enableIntegration = function enableIntegration(name, callback) { | ||
return { | ||
type: EVENTS.ENABLE_INTEGRATION, | ||
name: name, | ||
callback: callback | ||
}; | ||
}; | ||
var disableIntegration = function disableIntegration(name, callback) { | ||
return { | ||
type: EVENTS.DISABLE_INTEGRATION, | ||
name: name, | ||
callback: callback | ||
}; | ||
}; | ||
// Track State | ||
@@ -701,3 +839,3 @@ var initialState$3 = { | ||
var l = !state.lastEvent ? data : state.event; | ||
console.log('>>>>>>>>>>>> state.lastEvent', state.lastEvent); | ||
// console.log('>>>>>>>>>>>> state.lastEvent', state.lastEvent) | ||
// TODO fix last event. 9/25 Still need to fix | ||
@@ -717,3 +855,3 @@ return _extends({}, state, { | ||
return { | ||
type: EVENTS.TRACK_START, | ||
type: EVENTS.TRACK_INIT, | ||
eventName: eventName, | ||
@@ -802,5 +940,4 @@ data: data, | ||
var identify = function identify(userId, traits, options, callback) { | ||
console.log('identify', userId, traits, options); | ||
return { | ||
type: EVENTS.IDENTIFY_START, | ||
type: EVENTS.IDENTIFY_INIT, | ||
userId: userId, | ||
@@ -813,2 +950,37 @@ traits: traits, | ||
function get$1(obj, path) { | ||
var pathArr = getPathSegments(path); | ||
for (var i = 0; i < pathArr.length; i++) { | ||
if (!Object.prototype.propertyIsEnumerable.call(obj, pathArr[i])) { | ||
return; | ||
} | ||
obj = obj[pathArr[i]]; | ||
if (obj === undefined || obj === null) { | ||
if (i !== pathArr.length - 1) { | ||
return; | ||
} | ||
break; | ||
} | ||
} | ||
return obj; | ||
} | ||
function getPathSegments(path) { | ||
var pathArr = path.split('.'); | ||
var parts = []; | ||
for (var i = 0; i < pathArr.length; i++) { | ||
var p = pathArr[i]; | ||
while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) { | ||
p = p.slice(0, -1) + '.'; | ||
p += pathArr[++i]; | ||
} | ||
parts.push(p); | ||
} | ||
return parts; | ||
} | ||
// Only way commonJS will work | ||
@@ -854,3 +1026,3 @@ module.exports = function (config) { | ||
// core middlewares | ||
initialize, identifyMiddleware(getIntegrations), trackMiddleware(getIntegrations), pageMiddleware(getIntegrations), dynamicMiddlewares]); | ||
initialize, identifyMiddleware(getIntegrations), trackMiddleware(getIntegrations), pageMiddleware(getIntegrations), integrationMiddleware, dynamicMiddlewares]); | ||
@@ -867,3 +1039,3 @@ // initial analytics state keys | ||
var composeEnhancers = compose; | ||
if (inBrowser) { | ||
if (inBrowser && config.debug) { | ||
var withDevTools = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; | ||
@@ -894,3 +1066,3 @@ composeEnhancers = withDevTools; | ||
store.dispatch({ | ||
type: EVENTS.REGISTER_INTEGRATION, | ||
type: EVENTS.INTEGRATION_INIT, | ||
name: provider.NAMESPACE, | ||
@@ -921,7 +1093,3 @@ integration: provider | ||
{ | ||
console.log('intialize state', store.getState()); | ||
} | ||
return { | ||
var api = { | ||
// Get all state or state by key | ||
@@ -931,4 +1099,3 @@ getState: function getState(key) { | ||
if (key) { | ||
// TODO add dot notation and grab deeper values | ||
return state[key]; | ||
return get$1(state, key); | ||
} | ||
@@ -959,5 +1126,8 @@ return state; | ||
// get user data | ||
user: function user$$1() { | ||
// TODO add key to input and allow for pulling back specific values | ||
return store.getState().user; | ||
user: function user$$1(key) { | ||
var user$$1 = store.getState().user; | ||
if (key) { | ||
return get$1(user$$1, key); | ||
} | ||
return user$$1; | ||
}, | ||
@@ -989,7 +1159,2 @@ // analtyics.ready all integrations ready | ||
if (name === '*') { | ||
/* // store subscribe works but won't give current action context | ||
return store.subscribe(() => { | ||
callback(action, store) | ||
}) | ||
*/ | ||
var globalListener = function globalListener(store) { | ||
@@ -1029,5 +1194,11 @@ return function (next) { | ||
}, | ||
enableIntegration: function enableIntegration$$1(name, callback) { | ||
store.dispatch(enableIntegration(name, callback)); | ||
}, | ||
disableIntegration: function disableIntegration$$1(name, callback) { | ||
store.dispatch(disableIntegration(name, callback)); | ||
}, | ||
// TODO decide if this is good or bad ⊂◉‿◉つ. Exposing publicly could be bad | ||
addIntegration: function addIntegration(t) { | ||
// TODO if it stays, state loaded needs to be set. Re REGISTER_INTEGRATION above | ||
// TODO if it stays, state loaded needs to be set. Re INTEGRATION_INIT above | ||
// validate integration | ||
@@ -1042,3 +1213,3 @@ if ((typeof t === 'undefined' ? 'undefined' : _typeof(t)) === 'object') { | ||
store.dispatch({ | ||
type: EVENTS.REGISTER_INTEGRATION, | ||
type: EVENTS.INTEGRATION_INIT, | ||
name: t.NAMESPACE, | ||
@@ -1049,2 +1220,4 @@ integration: t | ||
}; | ||
return api; | ||
} | ||
@@ -1056,2 +1229,3 @@ | ||
var maxRetries = config.maxRetries; | ||
var NAMESPACE = provider.NAMESPACE; | ||
@@ -1061,6 +1235,6 @@ if (retryCount > maxRetries) { | ||
type: EVENTS.INTEGRATION_FAILED, | ||
name: provider.NAMESPACE | ||
name: NAMESPACE | ||
}); | ||
store.dispatch({ | ||
type: 'integration_failed:' + provider.NAMESPACE | ||
type: EVENTS.INTEGRATION_FAILED_NAME(NAMESPACE) | ||
}); | ||
@@ -1081,3 +1255,3 @@ return false; | ||
type: EVENTS.INTEGRATION_LOADED, | ||
name: provider.NAMESPACE | ||
name: NAMESPACE | ||
}); | ||
@@ -1087,3 +1261,3 @@ | ||
store.dispatch({ | ||
type: 'integration_ready:' + provider.NAMESPACE | ||
type: EVENTS.INTEGRATION_LOADED_NAME(NAMESPACE) | ||
}); | ||
@@ -1090,0 +1264,0 @@ |
// Core Analytic Events | ||
export default { | ||
INITIALIZE: 'analyticsInit', // 'analyticsInit' | ||
INITIALIZE: 'analyticsInit', | ||
HANDLE_PARAMS: 'params', | ||
SET_CAMPAIGN: 'campaign', | ||
READY: 'ready', // 'analyticsReady' | ||
/* Integration actions */ | ||
REGISTER_INTEGRATION: 'integration_init', // 'integrationInit' | ||
INTEGRATION_LOADED: 'integration_ready', // 'integrationLoaded' | ||
INTEGRATION_FAILED: 'integration_failed', // 'integrationFailed' | ||
ENABLE_INTEGRATION: 'enable_integration', // 'integrationEnabled' | ||
DISABLE_INTEGRATION: 'disable_integration', // 'integrationDisabled' | ||
INTEGRATION_INIT: 'integrationInit', | ||
INTEGRATION_LOADED: 'integrationLoaded', | ||
INTEGRATION_FAILED: 'integrationFailed', | ||
INTEGRATION_LOADED_NAME: (name) => `integrationLoaded:${name}`, | ||
INTEGRATION_FAILED_NAME: (name) => `integrationFailed:${name}`, | ||
// Todo finish this event | ||
INTEGRATION_ENABLED: 'integrationEnabled', | ||
INTEGRATION_DISABLE: 'integrationDisabled', | ||
ENABLE_INTEGRATION: 'enableIntegration', | ||
DISABLE_INTEGRATION: 'disableIntegration', | ||
READY: 'analyticsReady', | ||
/* Page actions */ | ||
PAGE_START: 'page_init', // 'pageInit' | ||
PAGE: 'page', // 'page' | ||
PAGE_COMPLETE: 'page_complete', // 'pageCompleted' | ||
PAGE_ABORT: 'page_abort', // 'pageAborted' // TODO add this | ||
PAGE_INIT: 'pageInit', | ||
PAGE: 'page', | ||
PAGE_NAMESPACE: (name) => `page:${name}`, | ||
PAGE_COMPLETE: 'pageCompleted', | ||
PAGE_ABORT: 'pageAborted', | ||
PAGE_TIME_OUT: 'pageTimedOut', | ||
/* Track actions */ | ||
TRACK_START: 'track_init', // 'trackInit' | ||
TRACK: 'track', // 'track' | ||
TRACK_COMPLETE: 'track_complete', // 'trackCompleted' | ||
TRACK_ABORT: 'track_abort', // 'trackAborted' | ||
TRACK_INIT: 'trackInit', | ||
TRACK: 'track', | ||
TRACK_NAMESPACE: (name) => `track:${name}`, | ||
TRACK_COMPLETE: 'trackCompleted', | ||
TRACK_ABORT: 'trackAborted', | ||
TRACK_TIME_OUT: 'trackTimedOut', | ||
/* Identify actions */ | ||
IDENTIFY_START: 'identify_init', // 'identifyInit' | ||
IDENTIFY: 'identify', // 'identify' | ||
IDENTIFY_COMPLETE: 'identify_complete', // 'identifyCompleted' | ||
IDENTIFY_ABORTED: 'identify_abort' // 'identifyAborted' // TODO add this | ||
IDENTIFY_INIT: 'identifyInit', | ||
IDENTIFY: 'identify', | ||
IDENTIFY_NAMESPACE: (name) => `identify:${name}`, | ||
IDENTIFY_COMPLETE: 'identifyCompleted', | ||
IDENTIFY_ABORTED: 'identifyAborted' // 'identifyAborted' // TODO add this | ||
} |
54
index.js
@@ -7,8 +7,10 @@ import { createStore, combineReducers, applyMiddleware, compose } from 'redux' | ||
import pageMiddleware from './middleware/pageMiddleware' | ||
import integrationMiddleware from './middleware/integrationMiddleware' | ||
import identifyMiddleware from './middleware/identifyMiddleware' | ||
import context, { makeContext } from './modules/context' | ||
import integrations from './modules/integrations' | ||
import integrations, { enableIntegration, disableIntegration } from './modules/integrations' | ||
import page, { pageView } from './modules/page' | ||
import track, { trackEvent } from './modules/track' | ||
import user, { identify } from './modules/user' | ||
import dotProp from './utils/dotProp' | ||
import EVENTS from './events' | ||
@@ -60,2 +62,3 @@ | ||
pageMiddleware(getIntegrations), | ||
integrationMiddleware, | ||
dynamicMiddlewares, | ||
@@ -74,3 +77,3 @@ ]) | ||
let composeEnhancers = compose | ||
if (inBrowser) { | ||
if (inBrowser && config.debug) { | ||
const withDevTools = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose | ||
@@ -105,3 +108,3 @@ composeEnhancers = (isDev) ? withDevTools : compose | ||
store.dispatch({ | ||
type: EVENTS.REGISTER_INTEGRATION, | ||
type: EVENTS.INTEGRATION_INIT, | ||
name: provider.NAMESPACE, | ||
@@ -132,7 +135,3 @@ integration: provider | ||
if (isDev) { | ||
console.log('intialize state', store.getState()) | ||
} | ||
return { | ||
const api = { | ||
// Get all state or state by key | ||
@@ -142,4 +141,3 @@ getState: (key) => { | ||
if (key) { | ||
// TODO add dot notation and grab deeper values | ||
return state[key] | ||
return dotProp(state, key) | ||
} | ||
@@ -176,5 +174,8 @@ return state | ||
// get user data | ||
user: () => { | ||
// TODO add key to input and allow for pulling back specific values | ||
return store.getState().user | ||
user: (key) => { | ||
const user = store.getState().user | ||
if (key) { | ||
return dotProp(user, key) | ||
} | ||
return user | ||
}, | ||
@@ -200,7 +201,2 @@ // analtyics.ready all integrations ready | ||
if (name === '*') { | ||
/* // store subscribe works but won't give current action context | ||
return store.subscribe(() => { | ||
callback(action, store) | ||
}) | ||
*/ | ||
const globalListener = store => next => action => { | ||
@@ -232,5 +228,11 @@ // do something on every action * | ||
}, | ||
enableIntegration: (name, callback) => { | ||
store.dispatch(enableIntegration(name, callback)) | ||
}, | ||
disableIntegration: (name, callback) => { | ||
store.dispatch(disableIntegration(name, callback)) | ||
}, | ||
// TODO decide if this is good or bad ⊂◉‿◉つ. Exposing publicly could be bad | ||
addIntegration: function(t) { | ||
// TODO if it stays, state loaded needs to be set. Re REGISTER_INTEGRATION above | ||
// TODO if it stays, state loaded needs to be set. Re INTEGRATION_INIT above | ||
// validate integration | ||
@@ -248,3 +250,3 @@ if (typeof t === 'object') { | ||
store.dispatch({ | ||
type: EVENTS.REGISTER_INTEGRATION, | ||
type: EVENTS.INTEGRATION_INIT, | ||
name: t.NAMESPACE, | ||
@@ -255,2 +257,4 @@ integration: t | ||
} | ||
return api | ||
} | ||
@@ -262,10 +266,10 @@ | ||
const maxRetries = config.maxRetries | ||
const { NAMESPACE } = provider | ||
if (retryCount > maxRetries) { | ||
store.dispatch({ | ||
type: EVENTS.INTEGRATION_FAILED, | ||
name: provider.NAMESPACE | ||
name: NAMESPACE | ||
}) | ||
store.dispatch({ | ||
type: `integration_failed:${provider.NAMESPACE}` | ||
type: EVENTS.INTEGRATION_FAILED_NAME(NAMESPACE) | ||
}) | ||
@@ -286,3 +290,3 @@ return false | ||
type: EVENTS.INTEGRATION_LOADED, | ||
name: provider.NAMESPACE | ||
name: NAMESPACE | ||
}) | ||
@@ -292,3 +296,3 @@ | ||
store.dispatch({ | ||
type: `integration_ready:${provider.NAMESPACE}` | ||
type: EVENTS.INTEGRATION_LOADED_NAME(NAMESPACE) | ||
}) | ||
@@ -295,0 +299,0 @@ |
@@ -8,4 +8,5 @@ import EVENTS from '../events' | ||
const { type, userId, traits, options, callback } = action | ||
if (type === EVENTS.IDENTIFY_START) { | ||
if (type === EVENTS.IDENTIFY_INIT) { | ||
const identifyCalls = getIntegrationsWithMethod(getIntegrations(), 'identify') | ||
const cb = getCallbackFromArgs(traits, options, callback) | ||
// No identify middleware attached | ||
@@ -24,5 +25,6 @@ if (!identifyCalls.length) { | ||
} | ||
let count = 0 | ||
let completed = [] | ||
let hasRan = false | ||
// console.log('identifyCalls', identifyCalls) | ||
@@ -45,4 +47,16 @@ /* Filter out disabled integrations */ | ||
const state = store.getState() | ||
const integrationLoaded = state.integrations[NAMESPACE].loaded | ||
if (!integrationLoaded) { | ||
const { loaded, enabled } = state.integrations[NAMESPACE] | ||
if (!enabled) { | ||
console.log('ABORT Identity viw >>>>>', NAMESPACE, type) | ||
count = count + 1 | ||
// all track calls complete | ||
if (identifyCalls === identifyCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
identifyCompleted(store, completed, cb) | ||
} | ||
return false | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
@@ -78,14 +92,12 @@ if (timer > timeoutMax) { | ||
/* Run namespaced .identify calls */ | ||
store.dispatch({ type: `identify:${NAMESPACE}` }) | ||
store.dispatch({ | ||
type: EVENTS.IDENTIFY_NAMESPACE(NAMESPACE) | ||
}) | ||
// increment success counter | ||
count = count + 1 | ||
completed = completed.concat(NAMESPACE) | ||
// all identify calls complete | ||
if (count === identifyCalls.length) { | ||
const cb = getCallbackFromArgs(traits, options, callback) | ||
if (cb) cb(state) | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
type: EVENTS.IDENTIFY_COMPLETE, | ||
}) | ||
identifyCompleted(store, completed, cb) | ||
} | ||
@@ -100,1 +112,12 @@ } | ||
} | ||
function identifyCompleted(store, completed, cb) { | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
type: EVENTS.IDENTIFY_COMPLETE, | ||
...{ integrations: completed } | ||
}) | ||
if (cb) { | ||
cb(store) | ||
} | ||
} |
@@ -9,3 +9,4 @@ import EVENTS from '../events' | ||
const { type, data, options, callback } = action | ||
if (type === EVENTS.PAGE_START) { | ||
if (type === EVENTS.PAGE_INIT) { | ||
const cb = getCallbackFromArgs(data, options, callback) | ||
const pageCalls = getIntegrationsWithMethod(getIntegrations(), 'page') | ||
@@ -25,2 +26,3 @@ // No page middleware attached | ||
let count = 0 | ||
let completed = [] | ||
let hasRan = false | ||
@@ -44,11 +46,22 @@ /* Handle all .page calls syncronously */ | ||
const state = store.getState() | ||
const { loaded, enabled } = state.integrations[NAMESPACE] | ||
const pageData = { ...getPageData(), ...data } | ||
const enrichedOptions = { ...state, ...{ options: options } } | ||
if (!state.integrations[NAMESPACE].loaded) { | ||
console.log('try again page', NAMESPACE) | ||
if (!enabled) { | ||
console.log('ABORT Page viw >>>>>', NAMESPACE, type) | ||
count = count + 1 | ||
// all track calls complete | ||
if (pageCalls === pageCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
pageCompleted(store, completed, cb) | ||
} | ||
return false | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
if (timer > timeoutMax) { | ||
store.dispatch({ | ||
type: 'pageTimeout', | ||
type: EVENTS.PAGE_TIME_OUT, | ||
name: NAMESPACE | ||
@@ -80,3 +93,3 @@ }) | ||
store.dispatch({ | ||
type: `page:${NAMESPACE}`, | ||
type: EVENTS.PAGE_NAMESPACE(NAMESPACE), | ||
data: pageData | ||
@@ -87,12 +100,7 @@ }) | ||
count = count + 1 | ||
completed = completed.concat(NAMESPACE) | ||
// all track calls complete | ||
if (count === pageCalls.length) { | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
type: EVENTS.PAGE_COMPLETE, | ||
}) | ||
const cb = getCallbackFromArgs(data, options, callback) | ||
if (cb) { | ||
cb(store) | ||
} | ||
pageCompleted(store, completed, cb) | ||
} | ||
@@ -107,1 +115,12 @@ } | ||
} | ||
function pageCompleted(store, completed, cb) { | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
type: EVENTS.PAGE_COMPLETE, | ||
...{ integrations: completed } | ||
}) | ||
if (cb) { | ||
cb(store) | ||
} | ||
} |
@@ -8,7 +8,3 @@ export default function formatPayload(eventName, payload) { | ||
} | ||
// why did I do this? | ||
// if (typeof eventName === 'string') { | ||
// data.eventName = eventName | ||
// } | ||
return data | ||
} |
@@ -9,5 +9,7 @@ import EVENTS from '../../events' | ||
const { type, eventName, data, options, callback } = action | ||
if (type === EVENTS.TRACK_START) { | ||
if (type === EVENTS.TRACK_INIT) { | ||
const dataObject = (data && typeof data === 'object') ? data : {} | ||
const cb = getCallbackFromArgs(data, options, callback) | ||
// format data payload | ||
const payload = formatPayload(eventName, data) | ||
const payload = formatPayload(eventName, dataObject) | ||
// setup data | ||
@@ -21,3 +23,4 @@ const dispatchData = { | ||
// if abort === true stop the rest | ||
if (action.abort) { | ||
if (action.abort || !eventName || typeof eventName !== 'string') { | ||
// Todo add reason why aborting happened | ||
store.dispatch({ | ||
@@ -27,2 +30,5 @@ ...{ type: EVENTS.TRACK_ABORT }, | ||
}) | ||
if (!eventName) { | ||
console.log('Missing eventName') | ||
} | ||
return next(action) | ||
@@ -32,2 +38,3 @@ } | ||
const trackCalls = getIntegrationsWithMethod(getIntegrations(), 'track') | ||
// No tracking middleware attached | ||
@@ -46,10 +53,10 @@ if (!trackCalls.length) { | ||
let trackCount = 0 | ||
let completed = [] | ||
let hasRan = false | ||
/* Filter out disabled integrations */ | ||
trackCalls.filter((provider) => { | ||
const integrations = options && options.integrations | ||
const disabled = integrations && integrations[provider.NAMESPACE] === false | ||
const integrationsOpts = options && options.integrations | ||
const disabled = integrationsOpts && integrationsOpts[provider.NAMESPACE] === false | ||
if (disabled) { | ||
console.log('ABORT TRACK>>>>>', provider.NAMESPACE, type) | ||
// console.log('ABORT TRACK>>>>>', provider.NAMESPACE, type) | ||
} | ||
@@ -65,14 +72,33 @@ return !disabled | ||
const state = store.getState() | ||
const { loaded, enabled } = state.integrations[NAMESPACE] | ||
// enrich options | ||
const enrichedOptions = { ...state, ...{ options: options } } | ||
// get callback from args passed in | ||
const integrationLoaded = state.integrations[NAMESPACE].loaded | ||
if (!integrationLoaded) { | ||
// Integration not enabled abort call | ||
if (!enabled) { | ||
// console.log('ABORT TRACK 2>>>>>', provider.NAMESPACE, type) | ||
trackCount = trackCount + 1 | ||
// all track calls complete | ||
if (trackCount === trackCalls.length) { | ||
// Todo this logic is duplicated above in after abort | ||
trackCompleted(dispatchData, state, completed, store, cb) | ||
} | ||
return false | ||
} | ||
if (!loaded) { | ||
// TODO: set max try limit and add calls to local queue on fail | ||
if (timer > timeoutMax) { | ||
// TODO send the event data with timestamp to `failedTrackCall` key? | ||
store.dispatch({ | ||
...dispatchData, | ||
...{ type: 'trackingTimeout' } | ||
...{ | ||
type: EVENTS.TRACK_TIME_OUT, | ||
integration: NAMESPACE | ||
} | ||
}) | ||
// TODO: save to queue | ||
// TODO: save to retry queue | ||
trackCompleted(dispatchData, state, completed, store, cb) | ||
return false | ||
@@ -102,7 +128,8 @@ } | ||
...{ | ||
type: `track:${NAMESPACE}`, | ||
integration: NAMESPACE, | ||
type: EVENTS.TRACK_NAMESPACE(NAMESPACE) | ||
}, | ||
...dispatchData | ||
}) | ||
completed = completed.concat(NAMESPACE) | ||
// increment success counter | ||
@@ -112,9 +139,4 @@ trackCount = trackCount + 1 | ||
if (trackCount === trackCalls.length) { | ||
const cb = getCallbackFromArgs(data, options, callback) | ||
if (cb) cb(state) | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
...{ type: EVENTS.TRACK_COMPLETE }, | ||
...dispatchData | ||
}) | ||
// Todo this logic is duplicated above in after abort | ||
trackCompleted(dispatchData, state, completed, store, cb) | ||
} | ||
@@ -128,1 +150,13 @@ } | ||
} | ||
function trackCompleted(dispatchData, state, completed, store, cb) { | ||
if (cb) { | ||
cb(state) | ||
} | ||
// dispatch completion event for middlewares | ||
store.dispatch({ | ||
...{ type: EVENTS.TRACK_COMPLETE }, | ||
...dispatchData, | ||
...{ integrations: completed } | ||
}) | ||
} |
@@ -9,4 +9,4 @@ // Integrations Reducer | ||
switch (action.type) { | ||
case EVENTS.REGISTER_INTEGRATION: | ||
// console.log('REGISTER_INTEGRATION', action.name) | ||
case EVENTS.INTEGRATION_INIT: | ||
// console.log('INTEGRATION_INIT', action.name) | ||
// console.log('action.integration', action.integration) | ||
@@ -38,3 +38,2 @@ newState[action.name] = { | ||
case EVENTS.DISABLE_INTEGRATION: | ||
// console.log('DISABLE_INTEGRATION', action.name) | ||
newState[action.name] = { | ||
@@ -45,2 +44,8 @@ ...state[action.name], | ||
return {...state, ...newState} | ||
case EVENTS.ENABLE_INTEGRATION: | ||
newState[action.name] = { | ||
...state[action.name], | ||
...{ enabled: true } | ||
} | ||
return {...state, ...newState} | ||
default: | ||
@@ -53,3 +58,3 @@ return state | ||
return { | ||
type: EVENTS.REGISTER_INTEGRATION, | ||
type: EVENTS.INTEGRATION_INIT, | ||
integration: integration | ||
@@ -59,14 +64,16 @@ } | ||
export const enableIntegration = (name) => { | ||
export const enableIntegration = (name, callback) => { | ||
return { | ||
type: EVENTS.ENABLE_INTEGRATION, | ||
name: name | ||
name: name, | ||
callback: callback | ||
} | ||
} | ||
export const disableIntegration = (name) => { | ||
export const disableIntegration = (name, callback) => { | ||
return { | ||
type: EVENTS.DISABLE_INTEGRATION, | ||
name: name | ||
name: name, | ||
callback: callback | ||
} | ||
} |
// Page View Module | ||
import { inBrowser } from 'analytics-utils' | ||
import EVENTS from '../events' | ||
import getIntegrationsWithMethod from '../utils/getIntegrationsWithMethod' | ||
import getCallbackFromArgs from '../utils/getCallback' | ||
@@ -45,3 +43,3 @@ export const getPageData = (pageData = {}) => { | ||
return { | ||
type: EVENTS.PAGE_START, | ||
type: EVENTS.PAGE_INIT, | ||
data: data, | ||
@@ -48,0 +46,0 @@ options: options, |
@@ -20,3 +20,3 @@ // Track Module | ||
const l = (!state.lastEvent) ? data : state.event | ||
console.log('>>>>>>>>>>>> state.lastEvent', state.lastEvent) | ||
// console.log('>>>>>>>>>>>> state.lastEvent', state.lastEvent) | ||
// TODO fix last event. 9/25 Still need to fix | ||
@@ -39,3 +39,3 @@ return { | ||
return { | ||
type: EVENTS.TRACK_START, | ||
type: EVENTS.TRACK_INIT, | ||
eventName: eventName, | ||
@@ -42,0 +42,0 @@ data: data, |
@@ -88,5 +88,4 @@ import { uuid, inBrowser } from 'analytics-utils' | ||
export const identify = (userId, traits, options, callback) => { | ||
console.log('identify', userId, traits, options) | ||
return { | ||
type: EVENTS.IDENTIFY_START, | ||
type: EVENTS.IDENTIFY_INIT, | ||
userId: userId, | ||
@@ -93,0 +92,0 @@ traits: traits, |
{ | ||
"name": "analytics", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"description": "Pluggable analytics library", | ||
@@ -87,3 +87,3 @@ "author": "David Wells", | ||
], | ||
"gitHead": "4340ab5efff41e0d54e46d2d3a0c6f051dabd783" | ||
"gitHead": "5cf32f6e32338e7cbd2217e2ab65bec00e79ffbc" | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
117477
12.81%25
8.7%3409
14.28%0
-100%