From 5548e15518c42145313db153fd149d605075a777 Mon Sep 17 00:00:00 2001 From: Jon Snyder Date: Thu, 8 Oct 2020 10:37:30 -0600 Subject: [PATCH 1/5] CORE-52172 expose ES modules so Launch extension can consume npm repo --- package-lock.json | 47 ++-- package.json | 21 +- rollup.config.js | 86 +++---- src/baseCode.js | 17 ++ src/baseCode/index.js | 4 +- .../EventMerge/createEventMergeId.js | 19 ++ src/components/EventMerge/index.js | 27 +-- src/components/Identity/configValidators.js | 7 +- src/constants/libraryName.js | 4 - src/constants/libraryVersion.js | 8 - src/core/index.js | 222 +++++++++--------- src/index.js | 22 ++ src/standalone.js | 17 ++ .../functional/helpers/createFixture/index.js | 6 +- .../specs/components/EventMerge/index.spec.js | 14 +- .../components/LibraryInfo/index.spec.js | 4 +- 16 files changed, 276 insertions(+), 249 deletions(-) create mode 100644 src/baseCode.js create mode 100644 src/components/EventMerge/createEventMergeId.js create mode 100644 src/index.js create mode 100644 src/standalone.js diff --git a/package-lock.json b/package-lock.json index 0f40fbc0c..9036b04dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,41 +5,46 @@ "requires": true, "dependencies": { "@adobe/reactor-cookie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@adobe/reactor-cookie/-/reactor-cookie-1.0.0.tgz", - "integrity": "sha512-MFHSHeuZxLkbe8A8WgXcuLdlOaVdbXzhzylUzVlJ3pOne0u0pmJUke5dXBIju7zCFk0rEJ0tjwR9eDjpcu8m1Q==", + "version": "1.1.0", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-adobe-release/@adobe/reactor-cookie/-/reactor-cookie-1.1.0.tgz", + "integrity": "sha1-nBMgH8TdQbdgCqkR5YdTm3ueQhY=", + "dev": true, "requires": { - "js-cookie": "2.1.4" + "js-cookie": "2.2.1" } }, "@adobe/reactor-load-script": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@adobe/reactor-load-script/-/reactor-load-script-1.1.1.tgz", - "integrity": "sha512-zshG46a+KpTPrSO2C5YJCZa1XEel2DNZijtsitHHsGMChQkSx6lfVH3JH2vuqUxCSq8bKC2eyBKcoDZkEZImgg==", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-adobe-release/@adobe/reactor-load-script/-/reactor-load-script-1.1.1.tgz", + "integrity": "sha1-Qbbm35itDeX6p11PZyyQ4mI6os0=", + "dev": true, "requires": { "@adobe/reactor-promise": "*" } }, "@adobe/reactor-object-assign": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@adobe/reactor-object-assign/-/reactor-object-assign-1.0.0.tgz", - "integrity": "sha512-WI3uplIKeFqqGYyU0IRbXwq+7Nk40EF40s7UmDNL5hdVkiDhEtXmWmbuGPjapKQfe3BoxMlH+pk/rxTva/DaUw==", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-adobe-release/@adobe/reactor-object-assign/-/reactor-object-assign-1.0.0.tgz", + "integrity": "sha1-m8Aty/8qKK1vVaDl/YDzfJP3Yko=", + "dev": true, "requires": { "object-assign": "4.1.1" } }, "@adobe/reactor-promise": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@adobe/reactor-promise/-/reactor-promise-1.2.0.tgz", - "integrity": "sha512-0haTPOfJRKvTuG5Sbja3xAFPdv8aJUz+CiU2ocV5F88az0g6fOwt4+NLlLKzJcbh7qcg6MjDMZopbNc0xqUUVg==", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-adobe-release/@adobe/reactor-promise/-/reactor-promise-1.2.0.tgz", + "integrity": "sha1-fvHvKFBAClrCCx1zRkAqNZ355HE=", + "dev": true, "requires": { "promise-polyfill": "8.1.3" } }, "@adobe/reactor-query-string": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@adobe/reactor-query-string/-/reactor-query-string-1.0.0.tgz", - "integrity": "sha512-Y6Cb9azVk+zIs9wEoOTMa01pzMqxFDPhRCfvZeW3YTAeR/b3kZOjD8loTpDt7bDj0vCZPRB2mhnVGOMCnsvBFQ==", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-adobe-release/@adobe/reactor-query-string/-/reactor-query-string-1.0.0.tgz", + "integrity": "sha1-5/b5vYnQqE2sWmxQIlXysgpWh8E=", + "dev": true, "requires": { "querystring": "0.2.0" } @@ -6759,9 +6764,10 @@ "dev": true }, "js-cookie": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.1.4.tgz", - "integrity": "sha1-2k7FA4ZvFJ0WTPJfV57zEBUCXY0=" + "version": "2.2.1", + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-adobe-release/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha1-aeEG3F1YBolFYpAqpbrsN0Tpsrg=", + "dev": true }, "js-levenshtein": { "version": "1.1.6", @@ -8075,7 +8081,8 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true }, "object-component": { "version": "0.0.3", @@ -8705,7 +8712,8 @@ "promise-polyfill": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz", - "integrity": "sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==" + "integrity": "sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==", + "dev": true }, "promisify-event": { "version": "1.0.0", @@ -8826,8 +8834,9 @@ }, "querystring": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "resolved": "https://artifactory.corp.adobe.com:443/artifactory/api/npm/npm-adobe-release/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true }, "querystringify": { "version": "2.1.1", diff --git a/package.json b/package.json index 6e083ea6b..d8cbee90b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@adobe/alloy", "version": "2.2.0", "description": "Client-Side SDK for Unified Data Collection", - "main": "src/core/index.js", + "module": "dist/index.js", "scripts": { "clean": "rimraf dist", "lint": "eslint --fix \"*.js\" \"src/**/*.js\" \"test/**/*.js\"", @@ -28,10 +28,9 @@ "prebuild": "npm run clean && npm run format && npm run lint", "build": "rollup -c", "prebuild:prod": "npm run prebuild", - "build:prod:standalone:unminified": "rollup -c --environment BUILD:prodStandalone", - "build:prod:standalone:minified": "rollup -c --environment MINIFY,BUILD:prodStandalone", - "build:prod:reactor:unminified": "rollup -c --environment BUILD:prodReactor", - "build:prod": "npm-run-all --parallel build:prod:standalone:unminified build:prod:standalone:minified build:prod:reactor:unminified", + "build:prod:unminified": "rollup -c --environment BUILD:prod", + "build:prod:minified": "rollup -c --environment MINIFY,BUILD:prod", + "build:prod": "npm-run-all --parallel build:prod:unminified build:prod:minified", "build:watch": "rollup -c -w", "build:basecode": "terser src/baseCode/index.js --mangle --compress unused=false", "sandbox": "cd sandbox && npm start", @@ -77,14 +76,20 @@ } ], "dependencies": { + "css.escape": "^1.5.1", + "uuid": "^3.3.2" + }, + "peerDependencies": { "@adobe/reactor-cookie": "^1.0.0", "@adobe/reactor-load-script": "^1.1.1", "@adobe/reactor-object-assign": "^1.0.0", - "@adobe/reactor-query-string": "^1.0.0", - "css.escape": "^1.5.1", - "uuid": "^3.3.2" + "@adobe/reactor-query-string": "^1.0.0" }, "devDependencies": { + "@adobe/reactor-cookie": "^1.0.0", + "@adobe/reactor-load-script": "^1.1.1", + "@adobe/reactor-object-assign": "^1.0.0", + "@adobe/reactor-query-string": "^1.0.0", "@babel/core": "^7.2.2", "@babel/plugin-proposal-object-rest-spread": "^7.3.2", "@babel/plugin-transform-template-literals": "^7.4.4", diff --git a/rollup.config.js b/rollup.config.js index 425bb71e5..77db44d18 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -11,7 +11,6 @@ governing permissions and limitations under the License. */ import path from "path"; -import jscc from "rollup-plugin-jscc"; import resolve from "rollup-plugin-node-resolve"; import commonjs from "rollup-plugin-commonjs"; import babel from "rollup-plugin-babel"; @@ -19,14 +18,12 @@ import { terser } from "rollup-plugin-terser"; import license from "rollup-plugin-license"; const buildTargets = { - PROD_STANDALONE: "prodStandalone", - PROD_REACTOR: "prodReactor", + PROD: "prod", DEV: "dev" }; const destDirectoryByBuildTarget = { - [buildTargets.PROD_STANDALONE]: "dist/standalone/", - [buildTargets.PROD_REACTOR]: "dist/reactor/", + [buildTargets.PROD]: "dist/", [buildTargets.DEV]: "sandbox/public/" }; @@ -37,12 +34,6 @@ const destDirectory = destDirectoryByBuildTarget[buildTarget]; const minifiedExtension = minify ? ".min" : ""; const plugins = [ - jscc({ - values: { - _DEV: buildTarget === buildTargets.DEV, - _REACTOR: buildTarget === buildTargets.PROD_REACTOR - } - }), resolve({ preferBuiltins: false, // Support the browser field in dependencies' package.json. @@ -67,52 +58,53 @@ if (buildTarget !== buildTargets.DEV) { ); } -const config = { - input: "src/core/index.js", +const config = []; + +if (buildTarget === buildTargets.PROD) { + config.push({ + input: "src/baseCode.js", + output: [ + { + file: `${destDirectory}baseCode${minifiedExtension}.js`, + format: "iife" + } + ], + plugins + }); +} + +config.push({ + input: "src/standalone.js", output: [ { file: `${destDirectory}alloy${minifiedExtension}.js`, - // For the Reactor-specific build, we need to use the CommonJS format - // for output instead of IIFE, otherwise Rollup doesn't know whether the - // "external" modules (as defined elsewhere in this configuration) are - // coming from global variables or from another CommonJS bundler, so - // it adds a bunch of cruft to accommodate and logs build warnings. - // Because we have to use the CommonJS format for the Reactor-specific - // build, we can't just use an "intro" that looks like: - // if (IE less than version 11) { - // console.warn("unsupported browser"); - // return; - // } - // because you can't "return" from a CommonJS module. Therefore, we have - // to do an if-else for an "intro" and "outro". - // If we do an if-else, we're not compliant with strict mode, because - // babel inserts its function declarations directly inside our if-else. - // Because function declarations are not allowed directly within an - // if-else in strict mode, we need to wrap babel's - // function declarations (and our own code) inside an IIFE. - // So, what we end up with is output using "format: cjs" but with an - // appropriate intro and outro that provides browser checking and an - // IIFE. This works for both Reactor-specific and standalone use cases. - format: "cjs", - // Allow non-IE browsers and IE11 - // document.documentMode was added in IE8, and is specific to IE. - // IE7 and lower are not ES5 compatible so will get a parse error loading - // the library. + format: "iife", intro: "if (document.documentMode && document.documentMode < 11) {\n" + " console.warn('The Adobe Experience Cloud Web SDK does not support IE 10 and below.');\n" + - "} else {\n" + - " (function() {", - outro: " })();\n}" + " return;\n" + + "}\n" } ], plugins -}; +}); -// If we're building for Reactor, we'll use Reactor's core modules -// (named @adobe/reactor-*) instead of including the packages directly. -if (buildTarget === buildTargets.PROD_REACTOR) { - config.external = name => /^@adobe\/reactor-/.test(name); +if (buildTarget === buildTargets.PROD && !minify) { + config.push({ + input: "src/index.js", + output: [ + { + file: `${destDirectory}index.js`, + format: "es" + } + ], + // The @adobe/reactor-* dependencies are specified as peerDependencies so no need to include them in the + // module build + external(name) { + return /^@adobe\/reactor-/.test(name); + }, + plugins + }); } export default config; diff --git a/src/baseCode.js b/src/baseCode.js new file mode 100644 index 000000000..cd34e8c43 --- /dev/null +++ b/src/baseCode.js @@ -0,0 +1,17 @@ +/* +Copyright 2020 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +// This file is used by rollup to create a base code example + +import baseCode from "./baseCode/index"; + +baseCode(["alloy"]); diff --git a/src/baseCode/index.js b/src/baseCode/index.js index b39a87b52..2b2eb4ad5 100644 --- a/src/baseCode/index.js +++ b/src/baseCode/index.js @@ -33,7 +33,7 @@ governing permissions and limitations under the License. * particularly sensitive to base code size. */ -(function(window, instanceNames) { +export default instanceNames => { instanceNames.forEach(function(instanceName) { if (!window[instanceName]) { // __alloyNS stores a name of each "instance", or in other words, each @@ -59,4 +59,4 @@ governing permissions and limitations under the License. window[instanceName].q = []; } }); -})(window, ["alloy"]); +}; diff --git a/src/components/EventMerge/createEventMergeId.js b/src/components/EventMerge/createEventMergeId.js new file mode 100644 index 000000000..17c2dc567 --- /dev/null +++ b/src/components/EventMerge/createEventMergeId.js @@ -0,0 +1,19 @@ +/* +Copyright 2019 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import { uuid } from "../../utils"; + +export default () => { + return { + eventMergeId: uuid() + }; +}; diff --git a/src/components/EventMerge/index.js b/src/components/EventMerge/index.js index e5d51bfea..6ee4cd267 100644 --- a/src/components/EventMerge/index.js +++ b/src/components/EventMerge/index.js @@ -10,27 +10,13 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -import { uuid } from "../../utils"; -import { callback } from "../../utils/validation"; - -const generateEventMergeIdResult = () => { - return { - eventMergeId: uuid() - }; -}; - -const createEventMerge = ({ config }) => { - // #if _REACTOR - // This is a way for the Event Merge ID data element in the Reactor extension - // to get an event merge ID synchronously since data elements are required - // to be synchronous. - config.reactorRegisterCreateEventMergeId(generateEventMergeIdResult); - // #endif +import createEventMergeId from "./createEventMergeId"; +const createEventMerge = () => { return { commands: { createEventMergeId: { - run: generateEventMergeIdResult + run: createEventMergeId } } }; @@ -39,11 +25,4 @@ const createEventMerge = ({ config }) => { createEventMerge.namespace = "EventMerge"; createEventMerge.configValidators = {}; -// #if _REACTOR -// Not much need to validate since we are our own consumer. -createEventMerge.configValidators.reactorRegisterCreateEventMergeId = callback().default( - () => {} -); -// #endif - export default createEventMerge; diff --git a/src/components/Identity/configValidators.js b/src/components/Identity/configValidators.js index 4c788b646..5c22d63f3 100644 --- a/src/components/Identity/configValidators.js +++ b/src/components/Identity/configValidators.js @@ -10,16 +10,11 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -import { boolean, callback } from "../../utils/validation"; +import { boolean } from "../../utils/validation"; const configValidators = { thirdPartyCookiesEnabled: boolean().default(true), idMigrationEnabled: boolean().default(true) }; -// #if _REACTOR -// Not much need to validate since we are our own consumer. -configValidators.reactorRegisterGetEcid = callback().default(() => {}); -// #endif - export default configValidators; diff --git a/src/constants/libraryName.js b/src/constants/libraryName.js index 887128929..52d0d3e4b 100644 --- a/src/constants/libraryName.js +++ b/src/constants/libraryName.js @@ -10,8 +10,4 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -/* #if _REACTOR -export default "https://ns.adobe.com/experience/alloy/reactor"; -//#else */ export default "https://ns.adobe.com/experience/alloy"; -// #endif diff --git a/src/constants/libraryVersion.js b/src/constants/libraryVersion.js index 529960d55..18c692536 100644 --- a/src/constants/libraryVersion.js +++ b/src/constants/libraryVersion.js @@ -11,14 +11,6 @@ governing permissions and limitations under the License. */ // The __VERSION__ keyword will be replace at alloy build time with the package.json version. -// The __EXTENSION_VERSION__ keyword will be replaced at extension build time with the -// launch extension's package.json version. // see babel-plugin-version -/* #if _REACTOR -const alloyVersion = "__VERSION__"; -const extensionVersion = "__EXTENSION_VERSION__"; -export default `${alloyVersion}+${extensionVersion}`; -//#else */ export default "__VERSION__"; -// #endif diff --git a/src/core/index.js b/src/core/index.js index 7d3d03e5f..5edb84388 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -38,127 +38,129 @@ import injectProcessWarningsAndErrors from "./edgeNetwork/injectProcessWarningsA import validateNetworkResponseIsWellFormed from "./edgeNetwork/validateNetworkResponseIsWellFormed"; import isRetryableHttpStatusCode from "./network/isRetryableHttpStatusCode"; -// eslint-disable-next-line no-underscore-dangle -const instanceNames = window.__alloyNS; +export default () => { + // eslint-disable-next-line no-underscore-dangle + const instanceNames = window.__alloyNS; -const createNamespacedStorage = injectStorage(window); + const createNamespacedStorage = injectStorage(window); -const { console } = window; + const { console } = window; -// set this up as a function so that monitors can be added at anytime -// eslint-disable-next-line no-underscore-dangle -const getMonitors = () => window.__alloyMonitors || []; + // set this up as a function so that monitors can be added at anytime + // eslint-disable-next-line no-underscore-dangle + const getMonitors = () => window.__alloyMonitors || []; -const coreConfigValidators = createCoreConfigs(); -const apexDomain = getApexDomain(window, cookieJar); + const coreConfigValidators = createCoreConfigs(); + const apexDomain = getApexDomain(window, cookieJar); -if (instanceNames) { - instanceNames.forEach(instanceName => { - const { - setDebugEnabled, - logger, - createComponentLogger - } = createLogController({ - console, - locationSearch: window.location.search, - createLogger, - instanceName, - createNamespacedStorage, - getMonitors - }); - const componentRegistry = createComponentRegistry(); - const lifecycle = createLifecycle(componentRegistry); - const networkStrategy = injectNetworkStrategy(window, logger); - - const setDebugCommand = options => { - setDebugEnabled(options.enabled, { fromConfig: false }); - }; - - const configureCommand = options => { - const config = buildAndValidateConfig({ - options, - componentCreators, - coreConfigValidators, - createConfig, + if (instanceNames) { + instanceNames.forEach(instanceName => { + const { + setDebugEnabled, logger, - setDebugEnabled - }); - const cookieTransfer = createCookieTransfer({ - cookieJar, - orgId: config.orgId, - apexDomain - }); - const sendNetworkRequest = injectSendNetworkRequest({ - logger, - networkStrategy, - isRetryableHttpStatusCode - }); - const processWarningsAndErrors = injectProcessWarningsAndErrors({ - logger - }); - const sendEdgeNetworkRequest = injectSendEdgeNetworkRequest({ - config, - lifecycle, - cookieTransfer, - sendNetworkRequest, - createResponse, - processWarningsAndErrors, - validateNetworkResponseIsWellFormed + createComponentLogger + } = createLogController({ + console, + locationSearch: window.location.search, + createLogger, + instanceName, + createNamespacedStorage, + getMonitors }); - const generalConsentState = createConsentStateMachine(); - const consent = createConsent({ - generalConsentState, + const componentRegistry = createComponentRegistry(); + const lifecycle = createLifecycle(componentRegistry); + const networkStrategy = injectNetworkStrategy(window, logger); + + const setDebugCommand = options => { + setDebugEnabled(options.enabled, { fromConfig: false }); + }; + + const configureCommand = options => { + const config = buildAndValidateConfig({ + options, + componentCreators, + coreConfigValidators, + createConfig, + logger, + setDebugEnabled + }); + const cookieTransfer = createCookieTransfer({ + cookieJar, + orgId: config.orgId, + apexDomain + }); + const sendNetworkRequest = injectSendNetworkRequest({ + logger, + networkStrategy, + isRetryableHttpStatusCode + }); + const processWarningsAndErrors = injectProcessWarningsAndErrors({ + logger + }); + const sendEdgeNetworkRequest = injectSendEdgeNetworkRequest({ + config, + lifecycle, + cookieTransfer, + sendNetworkRequest, + createResponse, + processWarningsAndErrors, + validateNetworkResponseIsWellFormed + }); + const generalConsentState = createConsentStateMachine(); + const consent = createConsent({ + generalConsentState, + logger + }); + const eventManager = createEventManager({ + config, + logger, + lifecycle, + consent, + createEvent, + createDataCollectionRequestPayload, + sendEdgeNetworkRequest + }); + return initializeComponents({ + componentCreators, + lifecycle, + componentRegistry, + getImmediatelyAvailableTools(componentName) { + const componentLogger = createComponentLogger(componentName); + return { + config, + consent, + eventManager, + logger: componentLogger, + lifecycle, + sendEdgeNetworkRequest, + handleError: injectHandleError({ + errorPrefix: `[${instanceName}] [${componentName}]`, + logger: componentLogger + }) + }; + } + }); + }; + + const handleError = injectHandleError({ + errorPrefix: `[${instanceName}]`, logger }); - const eventManager = createEventManager({ - config, + + const executeCommand = injectExecuteCommand({ logger, - lifecycle, - consent, - createEvent, - createDataCollectionRequestPayload, - sendEdgeNetworkRequest + configureCommand, + setDebugCommand, + handleError, + validateCommandOptions }); - return initializeComponents({ - componentCreators, - lifecycle, - componentRegistry, - getImmediatelyAvailableTools(componentName) { - const componentLogger = createComponentLogger(componentName); - return { - config, - consent, - eventManager, - logger: componentLogger, - lifecycle, - sendEdgeNetworkRequest, - handleError: injectHandleError({ - errorPrefix: `[${instanceName}] [${componentName}]`, - logger: componentLogger - }) - }; - } - }); - }; - const handleError = injectHandleError({ - errorPrefix: `[${instanceName}]`, - logger - }); + const instance = createInstance(executeCommand); - const executeCommand = injectExecuteCommand({ - logger, - configureCommand, - setDebugCommand, - handleError, - validateCommandOptions + const queue = window[instanceName].q; + queue.push = instance; + logger.logOnInstanceCreated({ instance }); + queue.forEach(instance); }); - - const instance = createInstance(executeCommand); - - const queue = window[instanceName].q; - queue.push = instance; - logger.logOnInstanceCreated({ instance }); - queue.forEach(instance); - }); -} + } +}; diff --git a/src/index.js b/src/index.js new file mode 100644 index 000000000..d0313c094 --- /dev/null +++ b/src/index.js @@ -0,0 +1,22 @@ +/* +Copyright 2020 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +// This file is used to rollup the code into an ES module version to be used by other npm projects +// like the launch extension. + +export { default as baseCode } from "./baseCode/index"; + +export { default as core } from "./core"; + +export { + default as createEventMergeId +} from "./components/EventMerge/createEventMergeId"; diff --git a/src/standalone.js b/src/standalone.js new file mode 100644 index 000000000..2889bdb56 --- /dev/null +++ b/src/standalone.js @@ -0,0 +1,17 @@ +/* +Copyright 2020 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +// This file is used by rollup to create the browser version that is uploaded to cdn + +import core from "./core"; + +core(); diff --git a/test/functional/helpers/createFixture/index.js b/test/functional/helpers/createFixture/index.js index 204440d5d..af8263879 100644 --- a/test/functional/helpers/createFixture/index.js +++ b/test/functional/helpers/createFixture/index.js @@ -11,11 +11,7 @@ const promisePolyfillPath = path.join( "..", "promisePolyfill/promise-polyfill.min.js" ); -const alloyLibraryPath = path.join( - __dirname, - "../../../../", - "dist/standalone/alloy.js" -); +const alloyLibraryPath = path.join(__dirname, "../../../../", "dist/alloy.js"); const networkLogger = createNetworkLogger(); diff --git a/test/unit/specs/components/EventMerge/index.spec.js b/test/unit/specs/components/EventMerge/index.spec.js index 38491fb1e..741cae5ac 100644 --- a/test/unit/specs/components/EventMerge/index.spec.js +++ b/test/unit/specs/components/EventMerge/index.spec.js @@ -17,14 +17,10 @@ const uuidv4Regex = /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[ describe("EventMerge", () => { let eventMerge; - let reactorRegisterCreateEventMergeId; beforeAll(() => { - reactorRegisterCreateEventMergeId = jasmine.createSpy(); eventMerge = createEventMerge({ - config: createConfig({ - reactorRegisterCreateEventMergeId - }) + config: createConfig() }); }); @@ -39,12 +35,4 @@ describe("EventMerge", () => { }); }); }); - - describe("reactor-specific functionality", () => { - it("registers a function for creating an event merge ID", () => { - const createEventMergeId = reactorRegisterCreateEventMergeId.calls.first() - .args[0]; - expect(uuidv4Regex.test(createEventMergeId().eventMergeId)).toBe(true); - }); - }); }); diff --git a/test/unit/specs/components/LibraryInfo/index.spec.js b/test/unit/specs/components/LibraryInfo/index.spec.js index 6245b8933..4e941d507 100644 --- a/test/unit/specs/components/LibraryInfo/index.spec.js +++ b/test/unit/specs/components/LibraryInfo/index.spec.js @@ -2,11 +2,9 @@ import createLibraryInfo from "../../../../../src/components/LibraryInfo"; describe("LibraryInfo", () => { it("returns library information", () => { - const alloyVersion = "__VERSION__"; - const extensionVersion = "__EXTENSION_VERSION__"; expect(createLibraryInfo().commands.getLibraryInfo.run()).toEqual({ libraryInfo: { - version: `${alloyVersion}+${extensionVersion}` + version: `__VERSION__` } }); }); From 8cdcc34b1fd78e6d81409e2bad4060e247cb5769 Mon Sep 17 00:00:00 2001 From: Jon Snyder Date: Mon, 12 Oct 2020 15:23:55 -0600 Subject: [PATCH 2/5] CORE-52172 add tests and ignores, add more terser options --- coverageignore.js | 8 +++++- package.json | 1 - rollup.config.js | 11 ++++++-- scripts/deploy_sandbox.sh | 10 +++---- src/components/EventMerge/createComponent.js | 21 +++++++++++++++ .../EventMerge/createEventMergeId.js | 2 +- src/components/EventMerge/index.js | 9 ++----- .../EventMerge/createComponent.spec.js | 26 ++++++++++++++++++ ...dex.spec.js => createEventMergeId.spec.js} | 27 +++++-------------- 9 files changed, 78 insertions(+), 37 deletions(-) create mode 100644 src/components/EventMerge/createComponent.js create mode 100644 test/unit/specs/components/EventMerge/createComponent.spec.js rename test/unit/specs/components/EventMerge/{index.spec.js => createEventMergeId.spec.js} (51%) diff --git a/coverageignore.js b/coverageignore.js index 14360c9d6..907d92910 100644 --- a/coverageignore.js +++ b/coverageignore.js @@ -14,4 +14,10 @@ governing permissions and limitations under the License. * Patterns of source files (files within the src directory) that should be * ignored for test coverage checks and reporting. */ -module.exports = ["**/.*", "**/constants/**", "**/index.js"]; +module.exports = [ + "**/.*", + "**/constants/**", + "**/index.js", + "src/baseCode.js", + "src/standAlone.js" +]; diff --git a/package.json b/package.json index d8cbee90b..c7304a099 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "build:prod:minified": "rollup -c --environment MINIFY,BUILD:prod", "build:prod": "npm-run-all --parallel build:prod:unminified build:prod:minified", "build:watch": "rollup -c -w", - "build:basecode": "terser src/baseCode/index.js --mangle --compress unused=false", "sandbox": "cd sandbox && npm start", "sandbox:install": "cd sandbox && npm install", "sandbox:build": "cd sandbox && npm run build", diff --git a/rollup.config.js b/rollup.config.js index 77db44d18..fd4f6aa23 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -45,7 +45,14 @@ const plugins = [ ]; if (minify) { - plugins.push(terser()); + plugins.push( + terser({ + mangle: true, + compress: { + unused: false + } + }) + ); } if (buildTarget !== buildTargets.DEV) { @@ -74,7 +81,7 @@ if (buildTarget === buildTargets.PROD) { } config.push({ - input: "src/standalone.js", + input: "src/standAlone.js", output: [ { file: `${destDirectory}alloy${minifiedExtension}.js`, diff --git a/scripts/deploy_sandbox.sh b/scripts/deploy_sandbox.sh index 02f02dd4e..67601f90d 100755 --- a/scripts/deploy_sandbox.sh +++ b/scripts/deploy_sandbox.sh @@ -1,5 +1,5 @@ -ssh -t mowla@20.186.4.13 "cd /var/www/alloyio.com && git reset HEAD --hard && -git pull origin master && npm i && npm run build:prod && npm run sandbox:install && -npm run sandbox:build && -cp /var/www/alloyio.com/dist/standalone/alloy.js /var/www/alloyio.com/sandbox/build && -cp /var/www/alloyio.com/dist/standalone/alloy.js /var/www/alloyio.com/sandbox/build/demo" \ No newline at end of file +ssh -t mowla@20.186.4.13 "cd /var/www/alloyio.com && git reset HEAD --hard && +git pull origin master && npm i && npm run build:prod && npm run sandbox:install && +npm run sandbox:build && +cp /var/www/alloyio.com/dist/alloy.js /var/www/alloyio.com/sandbox/build && +cp /var/www/alloyio.com/dist/alloy.js /var/www/alloyio.com/sandbox/build/demo" \ No newline at end of file diff --git a/src/components/EventMerge/createComponent.js b/src/components/EventMerge/createComponent.js new file mode 100644 index 000000000..86499873b --- /dev/null +++ b/src/components/EventMerge/createComponent.js @@ -0,0 +1,21 @@ +/* +Copyright 2020 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +export default ({ createEventMergeId }) => { + return { + commands: { + createEventMergeId: { + run: createEventMergeId + } + } + }; +}; diff --git a/src/components/EventMerge/createEventMergeId.js b/src/components/EventMerge/createEventMergeId.js index 17c2dc567..95c969feb 100644 --- a/src/components/EventMerge/createEventMergeId.js +++ b/src/components/EventMerge/createEventMergeId.js @@ -1,5 +1,5 @@ /* -Copyright 2019 Adobe. All rights reserved. +Copyright 20219 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/src/components/EventMerge/index.js b/src/components/EventMerge/index.js index 6ee4cd267..4a57a3ea9 100644 --- a/src/components/EventMerge/index.js +++ b/src/components/EventMerge/index.js @@ -11,15 +11,10 @@ governing permissions and limitations under the License. */ import createEventMergeId from "./createEventMergeId"; +import createComponent from "./createComponent"; const createEventMerge = () => { - return { - commands: { - createEventMergeId: { - run: createEventMergeId - } - } - }; + return createComponent(createEventMergeId); }; createEventMerge.namespace = "EventMerge"; diff --git a/test/unit/specs/components/EventMerge/createComponent.spec.js b/test/unit/specs/components/EventMerge/createComponent.spec.js new file mode 100644 index 000000000..693f792c8 --- /dev/null +++ b/test/unit/specs/components/EventMerge/createComponent.spec.js @@ -0,0 +1,26 @@ +/* +Copyright 2019 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import createComponent from "../../../../../src/components/EventMerge/createComponent"; + +describe("EventMerge:createComponent", () => { + it("creates a component", () => { + const createEventMergeId = () => undefined; + expect(createComponent({ createEventMergeId })).toEqual({ + commands: { + createEventMergeId: { + run: createEventMergeId + } + } + }); + }); +}); diff --git a/test/unit/specs/components/EventMerge/index.spec.js b/test/unit/specs/components/EventMerge/createEventMergeId.spec.js similarity index 51% rename from test/unit/specs/components/EventMerge/index.spec.js rename to test/unit/specs/components/EventMerge/createEventMergeId.spec.js index 741cae5ac..30c7f6180 100644 --- a/test/unit/specs/components/EventMerge/index.spec.js +++ b/test/unit/specs/components/EventMerge/createEventMergeId.spec.js @@ -1,5 +1,5 @@ /* -Copyright 2019 Adobe. All rights reserved. +Copyright 2020 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -10,29 +10,16 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -import createEventMerge from "../../../../../src/components/EventMerge"; -import createConfig from "../../../../../src/core/config/createConfig"; +import createEventMergeId from "../../../../../src/components/EventMerge/createEventMergeId"; const uuidv4Regex = /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i; -describe("EventMerge", () => { - let eventMerge; - - beforeAll(() => { - eventMerge = createEventMerge({ - config: createConfig() - }); +describe("EventMerge:createEventMergeId", () => { + it("returns a UUID v4-compliant Id", () => { + expect(uuidv4Regex.test(createEventMergeId().eventMergeId)).toBe(true); }); - describe("commands", () => { - describe("createEventMergeId", () => { - it("returns a UUID v4-compliant Id", () => { - expect( - uuidv4Regex.test( - eventMerge.commands.createEventMergeId.run().eventMergeId - ) - ).toBe(true); - }); - }); + it("doesn't return any other fields in the response", () => { + expect(Object.keys(createEventMergeId())).toEqual(["eventMergeId"]); }); }); From fdf619fa2c8eeca025e86a2c032cfb44e319f1af Mon Sep 17 00:00:00 2001 From: Jon Snyder Date: Wed, 14 Oct 2020 15:36:03 -0600 Subject: [PATCH 3/5] CORE-52172 add readme --- README.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da98aa131..bfbe4df52 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,7 @@ Alloy is the code name for the Adobe Experience Platform Web SDK. It allows for For documentation on how to use Alloy, please see the [user documentation](https://adobe.ly/36dGGp6). For documentation on how to contribute to Alloy, please see the [developer documentation](https://github.com/adobe/alloy/wiki). + +# Installation + + diff --git a/package.json b/package.json index c7304a099..145a7fa66 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@adobe/alloy", "version": "2.2.0", - "description": "Client-Side SDK for Unified Data Collection", + "description": "Adobe Experience Platform Web SDK", "module": "dist/index.js", "scripts": { "clean": "rimraf dist", From f4f37bab0d80c9538ac364c7ad88907de2adf7b3 Mon Sep 17 00:00:00 2001 From: Jon Snyder Date: Mon, 2 Nov 2020 16:43:14 -0700 Subject: [PATCH 4/5] CORE-52172 add test files to pass lint test --- test/unit/specs/baseCode.spec.js | 14 ++++++++++++++ test/unit/specs/standalone.spec.js | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/unit/specs/baseCode.spec.js create mode 100644 test/unit/specs/standalone.spec.js diff --git a/test/unit/specs/baseCode.spec.js b/test/unit/specs/baseCode.spec.js new file mode 100644 index 000000000..33436f4cb --- /dev/null +++ b/test/unit/specs/baseCode.spec.js @@ -0,0 +1,14 @@ +/* +Copyright 2020 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +// eslint-disable-next-line no-unused-vars +import baseCode from "../../../src/baseCode"; diff --git a/test/unit/specs/standalone.spec.js b/test/unit/specs/standalone.spec.js new file mode 100644 index 000000000..91fc9d2ca --- /dev/null +++ b/test/unit/specs/standalone.spec.js @@ -0,0 +1,14 @@ +/* +Copyright 2020 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +// eslint-disable-next-line no-unused-vars +import standalone from "../../../src/standalone"; From 621360659d824c7d9295a1012de5b99ab56ab0f2 Mon Sep 17 00:00:00 2001 From: Jon Snyder Date: Tue, 3 Nov 2020 13:38:23 -0700 Subject: [PATCH 5/5] CORE-52172 finish readme, setup files array, fix terser options --- README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- package.json | 3 +++ rollup.config.js | 23 +++++++++-------------- src/index.js | 4 +++- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index bfbe4df52..6b57dfd41 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,56 @@ # Alloy -Alloy is the code name for the Adobe Experience Platform Web SDK. It allows for streaming data into the platform, syncing identities, personalizing content, and more. +Alloy is the code name for the Adobe Experience Platform Web SDK. It allows for recording events into the Adobe Experience Platform, syncing identities, personalizing content, and more. For documentation on how to use Alloy, please see the [user documentation](https://adobe.ly/36dGGp6). For documentation on how to contribute to Alloy, please see the [developer documentation](https://github.com/adobe/alloy/wiki). -# Installation +## Installation + +There are three supported ways to use Alloy. + 1. Using Adobe Launch, install the Adobe Experience Platform Web SDK Extension. + 2. Use the pre-built, minified version available via a CDN. You could also self-host this version. + 3. Use the NPM library which exports an ES6 module. + +### Using the launch extension + +For documentation on the AEP Web SDK Launch Extension see the [launch documentation](https://docs.adobe.com/content/help/en/launch/using/extensions-ref/adobe-extension/aep-extension/overview.html) + +### Using the stand alone version + +```html + + + +``` + +### Using the NPM library + +```bash +npm install @adobe/alloy +``` + +Using the library: + +```javascript +import { baseCode, core } from "@adobe/alloy"; +baseCode(["alloy"]); // creates the window.alloy function +core(); // runs + +window.alloy("config", { ... }); +window.alloy("sendEvent", { ... }); +``` + +The ES6 exports are exposed via the NPM "module" property, so you may need to adjust your rollup system to look for the module property. diff --git a/package.json b/package.json index b551ca8df..5e3fff745 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "2.2.0", "description": "Adobe Experience Platform Web SDK", "module": "dist/index.js", + "files": [ + "dist/index.js" + ], "scripts": { "clean": "rimraf dist", "lint": "eslint --fix \"*.js\" \"src/**/*.js\" \"test/**/*.js\"", diff --git a/rollup.config.js b/rollup.config.js index 41a347e4e..ec49fcc5f 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -32,6 +32,12 @@ const minify = process.env.MINIFY; const destDirectory = destDirectoryByBuildTarget[buildTarget]; const minifiedExtension = minify ? ".min" : ""; +const baseCodeTerser = terser({ + mangle: true, + compress: { + unused: false + } +}); const plugins = [ resolve({ @@ -44,17 +50,6 @@ const plugins = [ babel() ]; -if (minify) { - plugins.push( - terser({ - mangle: true, - compress: { - unused: false - } - }) - ); -} - if (buildTarget !== buildTargets.DEV) { plugins.push( license({ @@ -78,7 +73,7 @@ if (buildTarget === buildTargets.PROD) { format: "iife" } ], - plugins + plugins: minify ? [...plugins, baseCodeTerser] : plugins }); } @@ -95,7 +90,7 @@ config.push({ "}\n" } ], - plugins + plugins: minify ? [...plugins, terser()] : plugins }); if (buildTarget === buildTargets.PROD && !minify) { @@ -108,7 +103,7 @@ if (buildTarget === buildTargets.PROD && !minify) { } ], // The @adobe/reactor-* dependencies are specified as peerDependencies so no need to include them in the - // module build + // module build. The Launch extension does not need them included. external(name) { return /^@adobe\/reactor-/.test(name); }, diff --git a/src/index.js b/src/index.js index d0313c094..1bf2594f2 100644 --- a/src/index.js +++ b/src/index.js @@ -11,12 +11,14 @@ governing permissions and limitations under the License. */ // This file is used to rollup the code into an ES module version to be used by other npm projects -// like the launch extension. +// like the launch extension. Everything that is exported here can be used independently by other +// npm projects. export { default as baseCode } from "./baseCode/index"; export { default as core } from "./core"; +// createEventMergeId is used by the Launch extension to provide a synchronous way to create an id export { default as createEventMergeId } from "./components/EventMerge/createEventMergeId";