Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support web worker env #467

Merged
merged 2 commits into from
Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ clean:

test: build
@$(KARMA) start karma.conf.js
@$(KARMA) start karma-web-worker.conf.js

test-sauce: build
@$(KARMA) start karma.conf.js --browsers sauce_chrome_windows
Expand Down
36 changes: 36 additions & 0 deletions karma-web-worker.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module.exports = config => {
config.set({
frameworks: ['mocha-webworker'],
files: [
{
pattern: 'test/web-worker.js',
included: false,
},
{
pattern: 'amplitude.js',
included: false,
},
{
pattern: 'node_modules/sinon/pkg/sinon.js',
included: false,
},
],
browsers: ['ChromeHeadless'],
autoWatch: false,
singleRun: true,
reporters: ['mocha'],
client: {
mochaWebWorker: {
pattern: [
'test/web-worker.js',
'amplitude.js',
'node_modules/sinon/pkg/sinon.js'
],
worker: 'Worker',
mocha: {
ui: 'bdd'
}
}
}
});
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"karma-firefox-launcher": "^1.0.1",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.5",
"karma-mocha-webworker": "^1.3.0",
"karma-sauce-launcher": "^2.0.2",
"karma-sinon": "^1.0.5",
"karma-sourcemap-loader": "^0.3.7",
Expand Down
21 changes: 13 additions & 8 deletions src/amplitude-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import getHost from './get-host';
import baseCookie from './base-cookie';
import { AmplitudeServerZone, getEventLogApi } from './server-zone';
import ConfigManager from './config-manager';
import GlobalScope from './global-scope';

/**
* AmplitudeClient SDK API - instance constructor.
Expand All @@ -28,7 +29,7 @@ import ConfigManager from './config-manager';
* @example var amplitudeClient = new AmplitudeClient();
*/
var AmplitudeClient = function AmplitudeClient(instanceName) {
if (!isBrowserEnv()) {
if (!isBrowserEnv() && !utils.isWebWorkerEnvironment()) {
utils.log.warn(
'amplitude-js will not work in a non-browser environment. If you are planning to add Amplitude to a node environment, please use @amplitude/node',
);
Expand Down Expand Up @@ -80,7 +81,11 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o

try {
_parseConfig(this.options, opt_config);
if (isBrowserEnv() && window.Prototype !== undefined && Array.prototype.toJSON) {
if (
(isBrowserEnv() || utils.isWebWorkerEnvironment()) &&
GlobalScope.Prototype !== undefined &&
Array.prototype.toJSON
) {
prototypeJsFix();
utils.log.warn(
'Prototype.js injected Array.prototype.toJSON. Deleting Array.prototype.toJSON to prevent double-stringify',
Expand Down Expand Up @@ -243,7 +248,7 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
// Monitoring just page exits because that is the most requested feature for now
// "If you're specifically trying to detect page unload events, the pagehide event is the best option."
// https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event
window.addEventListener(
GlobalScope.addEventListener(
'pagehide',
() => {
handleVisibilityChange();
Expand All @@ -254,7 +259,7 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
}
} catch (err) {
utils.log.error(err);
if (type(opt_config.onError) === 'function') {
if (opt_config && type(opt_config.onError) === 'function') {
opt_config.onError(err);
}
}
Expand All @@ -272,7 +277,7 @@ AmplitudeClient.prototype.deleteLowerLevelDomainCookies = function () {
const cookieHost =
this.options.domain && this.options.domain[0] === '.' ? this.options.domain.slice(1) : this.options.domain;

if (!cookieHost) {
if (!cookieHost || !utils.isWebWorkerEnvironment()) {
return;
}

Expand Down Expand Up @@ -751,14 +756,14 @@ var _sendParamsReferrerUserProperties = function _sendParamsReferrerUserProperti
* @private
*/
AmplitudeClient.prototype._getReferrer = function _getReferrer() {
return document.referrer;
return typeof document !== 'undefined' ? document.referrer : '';
};

/**
* @private
*/
AmplitudeClient.prototype._getUrlParams = function _getUrlParams() {
return location.search;
return GlobalScope.location.search;
};

/**
Expand Down Expand Up @@ -1779,7 +1784,7 @@ AmplitudeClient.prototype.sendEvents = function sendEvents() {
}
this._sending = true;
}
var protocol = this.options.forceHttps ? 'https' : 'https:' === window.location.protocol ? 'https' : 'http';
var protocol = this.options.forceHttps ? 'https' : 'https:' === GlobalScope.location.protocol ? 'https' : 'http';
var url = protocol + '://' + this.options.apiEndpoint;

// fetch events to send
Expand Down
3 changes: 3 additions & 0 deletions src/base-cookie.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ const sortByEventTime = (cookies) => {
// test that cookies are enabled - navigator.cookiesEnabled yields false positives in IE, need to test directly
const areCookiesEnabled = (opts = {}) => {
const cookieName = Constants.COOKIE_TEST_PREFIX + base64Id();
if (typeof document === 'undefined') {
return false;
}
let _areCookiesEnabled = false;
try {
const uid = String(new Date());
Expand Down
9 changes: 5 additions & 4 deletions src/base64.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import UTF8 from './utf8';
import GlobalScope from './global-scope';

/*
* Base64 encoder/decoder
Expand All @@ -9,8 +10,8 @@ var Base64 = {

encode: function (input) {
try {
if (window.btoa && window.atob) {
return window.btoa(unescape(encodeURIComponent(input)));
if (GlobalScope.btoa && GlobalScope.atob) {
return GlobalScope.btoa(unescape(encodeURIComponent(input)));
}
} catch (e) {
//log(e);
Expand Down Expand Up @@ -53,8 +54,8 @@ var Base64 = {

decode: function (input) {
try {
if (window.btoa && window.atob) {
return decodeURIComponent(escape(window.atob(input)));
if (GlobalScope.btoa && GlobalScope.atob) {
return decodeURIComponent(escape(GlobalScope.atob(input)));
}
} catch (e) {
//log(e);
Expand Down
7 changes: 4 additions & 3 deletions src/config-manager.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Constants from './constants';
import { getDynamicConfigApi } from './server-zone';
import GlobalScope from './global-scope';
/**
* Dynamic Configuration
* Find the best server url automatically based on app users' geo location.
Expand All @@ -15,14 +16,14 @@ class ConfigManager {

refresh(serverZone, forceHttps, callback) {
let protocol = 'https';
if (!forceHttps && 'https:' !== window.location.protocol) {
if (!forceHttps && 'https:' !== GlobalScope.location.protocol) {
protocol = 'http';
}
const dynamicConfigUrl = protocol + '://' + getDynamicConfigApi(serverZone);
const self = this;
const isIE = window.XDomainRequest ? true : false;
const isIE = GlobalScope.XDomainRequest ? true : false;
if (isIE) {
const xdr = new window.XDomainRequest();
const xdr = new GlobalScope.XDomainRequest();
xdr.open('GET', dynamicConfigUrl, true);
xdr.onload = function () {
const response = JSON.parse(xdr.responseText);
Expand Down
3 changes: 2 additions & 1 deletion src/cookiestorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import Cookie from './cookie';
import localStorage from './localstorage';
import baseCookie from './base-cookie';
import GlobalScope from './global-scope';

var cookieStorage = function () {
this.storage = null;
Expand Down Expand Up @@ -43,7 +44,7 @@ cookieStorage.prototype.getStorage = function () {
this._options.expirationDays = opts.expirationDays || this._options.expirationDays;
// localStorage is specific to subdomains
this._options.domain =
opts.domain || this._options.domain || (window && window.location && window.location.hostname);
opts.domain || this._options.domain || (GlobalScope && GlobalScope.location && GlobalScope.location.hostname);
return (this._options.secure = opts.secure || false);
},
get: function (name) {
Expand Down
17 changes: 14 additions & 3 deletions src/get-host.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import GlobalScope from './global-scope';

const getHost = (url) => {
const a = document.createElement('a');
a.href = url;
return a.hostname || location.hostname;
if (url) {
if (typeof document !== 'undefined') {
const a = document.createElement('a');
a.href = url;
return a.hostname || GlobalScope.location.hostname;
}
if (typeof URL === 'function') {
const u = new URL(url);
return u.hostname || GlobalScope.location.hostname;
}
}
return GlobalScope.location.hostname;
};

export default getHost;
4 changes: 3 additions & 1 deletion src/get-location.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import GlobalScope from './global-scope';

const getLocation = () => {
return window.location;
return GlobalScope.location;
};

export default getLocation;
2 changes: 2 additions & 0 deletions src/global-scope.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const GlobalScope = typeof window !== 'undefined' ? window : self;
export default GlobalScope;
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Entry point
import Amplitude from './amplitude';
import GlobalScope from './global-scope';

const old = (typeof window !== 'undefined' && window.amplitude) || {};
const old = (typeof GlobalScope !== 'undefined' && GlobalScope.amplitude) || {};
const newInstance = new Amplitude();
newInstance._q = old._q || [];

Expand Down
21 changes: 14 additions & 7 deletions src/localstorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
* Implement localStorage to support Firefox 2-3 and IE 5-7
*/

import GlobalScope from './global-scope';
import WorkerStorage from './worker-storage';
import utils from './utils';

var localStorage;

if (!BUILD_COMPAT_LOCAL_STORAGE) {
localStorage = window.localStorage;
localStorage = GlobalScope.localStorage;
}

if (BUILD_COMPAT_LOCAL_STORAGE) {
Expand All @@ -14,9 +18,9 @@ if (BUILD_COMPAT_LOCAL_STORAGE) {
var uid = new Date();
var result;
try {
window.localStorage.setItem(uid, uid);
result = window.localStorage.getItem(uid) === String(uid);
window.localStorage.removeItem(uid);
GlobalScope.localStorage.setItem(uid, uid);
result = GlobalScope.localStorage.getItem(uid) === String(uid);
GlobalScope.localStorage.removeItem(uid);
return result;
} catch (e) {
// localStorage not available
Expand All @@ -25,12 +29,12 @@ if (BUILD_COMPAT_LOCAL_STORAGE) {
};

if (windowLocalStorageAvailable()) {
localStorage = window.localStorage;
} else if (typeof window !== 'undefined' && window.globalStorage) {
localStorage = GlobalScope.localStorage;
} else if (typeof GlobalScope !== 'undefined' && GlobalScope.globalStorage) {
// Firefox 2-3 use globalStorage
// See https://developer.mozilla.org/en/dom/storage#globalStorage
try {
localStorage = window.globalStorage[window.location.hostname];
localStorage = GlobalScope.globalStorage[GlobalScope.location.hostname];
} catch (e) {
// Something bad happened...
}
Expand Down Expand Up @@ -85,6 +89,9 @@ if (BUILD_COMPAT_LOCAL_STORAGE) {
} else {
/* Nothing we can do ... */
}
} else if (utils.isWebWorkerEnvironment()) {
// Web worker
localStorage = new WorkerStorage();
}
if (!localStorage) {
/* eslint-disable no-unused-vars */
Expand Down
11 changes: 6 additions & 5 deletions src/metadata-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import getLocation from './get-location';
import ampLocalStorage from './localstorage';
import topDomain from './top-domain';
import utils from './utils';
import GlobalScope from './global-scope';

const storageOptionExists = {
[Constants.STORAGE_COOKIES]: true,
Expand Down Expand Up @@ -88,8 +89,8 @@ class MetadataStorage {

switch (this.storage) {
case Constants.STORAGE_SESSION:
if (window.sessionStorage) {
window.sessionStorage.setItem(this.storageKey, value);
if (GlobalScope.sessionStorage) {
GlobalScope.sessionStorage.setItem(this.storageKey, value);
}
break;
case Constants.STORAGE_LOCAL:
Expand Down Expand Up @@ -131,7 +132,7 @@ class MetadataStorage {
}
if (!str) {
try {
str = window.sessionStorage && window.sessionStorage.getItem(this.storageKey);
str = GlobalScope.sessionStorage && GlobalScope.sessionStorage.getItem(this.storageKey);
} catch (e) {
utils.log.info(`window.sessionStorage unavailable. Reason: "${e}"`);
}
Expand Down Expand Up @@ -187,8 +188,8 @@ class MetadataStorage {
}
if (!str) {
try {
str = window.sessionStorage && window.sessionStorage.getItem(this.storageKey);
window.sessionStorage.clear();
str = GlobalScope.sessionStorage && GlobalScope.sessionStorage.getItem(this.storageKey);
GlobalScope.sessionStorage.clear();
} catch (e) {
utils.log.info(`window.sessionStorage unavailable. Reason: "${e}"`);
}
Expand Down
3 changes: 3 additions & 0 deletions src/top-domain.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import baseCookie from './base-cookie';
import base64Id from './base64Id';
import getHost from './get-host';
import utils from './utils';

// Utility that finds top level domain to write to
const topDomain = (url) => {
Expand All @@ -9,6 +10,8 @@ const topDomain = (url) => {
const levels = [];
const cname = '_tldtest_' + base64Id();

if (utils.isWebWorkerEnvironment()) return '';

for (let i = parts.length - 2; i >= 0; --i) {
levels.push(parts.slice(i).join('.'));
}
Expand Down
Loading