From f73597d7d19ecd000e46723906c0757796fa52f5 Mon Sep 17 00:00:00 2001
From: Wyatt Johnson
Date: Wed, 13 May 2020 16:47:45 +0000
Subject: [PATCH] [CORL-1013] Count Reset (#2960)
* feat: added reset option for count.js
* fix: adjust reset beheviour
* fix: switched to bundlesize2
* fix: added flag to enable github checks
Co-authored-by: Vinh
---
.circleci/config.yml | 16 +-
package.json | 4 +
src/core/client/count/index.ts | 56 ++++-
src/core/client/count/injectJSONPCallback.ts | 5 +-
.../test/__snapshots__/basic.spec.ts.snap | 200 +++++++++++++++++-
src/core/client/count/test/basic.spec.ts | 36 +++-
src/core/client/framework/utils/jsonp.ts | 32 +--
.../server/app/handlers/api/story/count.ts | 92 ++++----
8 files changed, 356 insertions(+), 85 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index eb7babba3..df0979e35 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,8 +1,8 @@
# job_environment will setup the environment for any job being executed.
job_environment: &job_environment
- NODE_ENV: test
- WEBPACK_MAX_CORES: 4
- NODE_OPTIONS: --max-old-space-size=8192
+ NODE_ENV: "test"
+ WEBPACK_MAX_CORES: "4"
+ NODE_OPTIONS: "--max-old-space-size=8192"
# job_defaults applies all the defaults for each job.
job_defaults: &job_defaults
@@ -49,7 +49,8 @@ jobs:
- ~/.npm
- persist_to_workspace:
root: .
- paths: node_modules
+ paths:
+ - node_modules
# lint will perform file linting.
lint:
@@ -78,7 +79,7 @@ jobs:
<<: *job_defaults
environment:
<<: *job_environment
- CI: true
+ CI: "true"
JEST_JUNIT_OUTPUT: "reports/junit/js-test-results.xml"
steps:
- checkout
@@ -115,14 +116,15 @@ jobs:
no_output_timeout: 30m
- run:
name: Verify Bundle Size
- command: npx bundlesize
+ command: npx bundlesize2 --enable-github-checks
- save_cache:
key: v1-build-cache-{{ .Branch }}-{{ .Revision }}
paths:
- ./dist
- persist_to_workspace:
root: .
- paths: dist
+ paths:
+ - dist
# docker_tests will test that the docker build process completes.
docker_tests:
diff --git a/package.json b/package.json
index c21f8d350..59225f4a2 100644
--- a/package.json
+++ b/package.json
@@ -420,6 +420,10 @@
{
"path": "./dist/static/assets/js/embed.js",
"maxSize": "15 kB"
+ },
+ {
+ "path": "./dist/static/assets/js/count.js",
+ "maxSize": "2 kB"
}
],
"graphql-schema-linter": {
diff --git a/src/core/client/count/index.ts b/src/core/client/count/index.ts
index e1b6ba00e..ef7cefae0 100644
--- a/src/core/client/count/index.ts
+++ b/src/core/client/count/index.ts
@@ -10,49 +10,89 @@ import injectJSONPCallback from "./injectJSONPCallback";
interface CountQueryArgs {
id?: string;
url?: string;
- notext?: boolean;
+ notext: boolean;
}
/** createCountQueryRef creates a unique reference from the query args */
function createCountQueryRef(args: CountQueryArgs) {
- return btoa(`${JSON.stringify(!!args.notext)};${args.id || args.url}`);
+ return btoa(`${args.notext ? "true" : "false"};${args.id || args.url}`);
+}
+
+interface DetectAndInjectArgs {
+ reset?: boolean;
}
/** Detects count elements and use jsonp to inject the counts. */
-function detectAndInject() {
+function detectAndInject(opts: DetectAndInjectArgs = {}) {
const ORIGIN = getCurrentScriptOrigin(ORIGIN_FALLBACK_ID);
const STORY_URL = resolveStoryURL();
+
/** A map of references pointing to the count query arguments */
const queryMap: Record = {};
// Find all the selected elements and fill the queryMap.
const elements = document.querySelectorAll(COUNT_SELECTOR);
Array.prototype.forEach.call(elements, (element: HTMLElement) => {
- let url = element.dataset.coralUrl;
const id = element.dataset.coralId;
const notext = element.dataset.coralNotext === "true";
+
+ // If there is no URL or ID on the element, add one based on the story url
+ // that we detected.
+ let url = element.dataset.coralUrl;
if (!url && !id) {
url = STORY_URL;
element.dataset.coralUrl = STORY_URL;
}
+
+ // Construct the args for generating the ref.
const args = { id, url, notext };
- const ref = createCountQueryRef(args);
+
+ // Get or create a ref.
+ let ref = element.dataset.coralRef;
+ if (!ref) {
+ ref = createCountQueryRef(args);
+ element.dataset.coralRef = ref;
+ } else {
+ // The element already had a ref attached to it, which means it's already
+ // been processed. If we aren't resetting, we should skip this.
+ if (!opts.reset) {
+ return;
+ }
+ }
+
+ // Add it to the managed set if we haven't already.
if (!(ref in queryMap)) {
queryMap[ref] = args;
}
- element.dataset.coralRef = ref;
});
// Call server using JSONP.
Object.keys(queryMap).forEach((ref) => {
const { url, id, notext } = queryMap[ref];
- const args = { url, id, notext: notext ? "true" : "false", ref };
+
+ // Compile the arguments used to generate the
+ const args: Record = {
+ url,
+ id,
+ notext: notext ? "true" : "false",
+ ref,
+ };
+
+ // Special handling for when the count is reset.
+ if (opts.reset) {
+ // Add the date as an argument to cache bust.
+ args.d = Date.now().toString();
+ }
+
+ // Add the script element with the specified options to the page.
jsonp(`${ORIGIN}/api/story/count.js`, "CoralCount.setCount", args);
});
}
export function main() {
- injectJSONPCallback();
+ // Inject the JSONP callback with the detection script to be used as the
+ // CoralCount.getCount callback.
+ injectJSONPCallback(detectAndInject);
detectAndInject();
}
diff --git a/src/core/client/count/injectJSONPCallback.ts b/src/core/client/count/injectJSONPCallback.ts
index 11b2648f7..a961b92fb 100644
--- a/src/core/client/count/injectJSONPCallback.ts
+++ b/src/core/client/count/injectJSONPCallback.ts
@@ -1,7 +1,9 @@
import { COUNT_SELECTOR } from "coral-framework/constants";
+type GetCountFunction = (opts?: { reset?: boolean }) => void;
+
/** Injects a global CoralCount callback into the window object to be used in JSONP */
-function injectJSONPCallback() {
+function injectJSONPCallback(getCount: GetCountFunction) {
(window as any).CoralCount = {
setCount: (data: { ref: string; html: string }) => {
// Find all the elements with ref.
@@ -12,6 +14,7 @@ function injectJSONPCallback() {
element.innerHTML = data.html;
});
},
+ getCount,
};
}
diff --git a/src/core/client/count/test/__snapshots__/basic.spec.ts.snap b/src/core/client/count/test/__snapshots__/basic.spec.ts.snap
index 1329505bc..a1c91425f 100644
--- a/src/core/client/count/test/__snapshots__/basic.spec.ts.snap
+++ b/src/core/client/count/test/__snapshots__/basic.spec.ts.snap
@@ -24,13 +24,205 @@ exports[`Calls JSONP 1`] = `
data-coral-url="http://localhost:8080/"
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+