diff --git a/README.md b/README.md index 2330f20f..18f6fdc3 100644 --- a/README.md +++ b/README.md @@ -14,26 +14,30 @@ Whether you need to visualize one thousand cells or one million, cellxgene helps # Getting started + ### The comprehensive guide to cellxgene + [The cellxgene documentation is your one-stop-shop for information about cellxgene](https://chanzuckerberg.github.io/cellxgene/)! You may be particularly interested in: -* Seeing [what cellxgene can do](https://chanzuckerberg.github.io/cellxgene/posts/gallery) -* Learning more about cellxgene [installation](https://chanzuckerberg.github.io/cellxgene/posts/install) and [usage](https://chanzuckerberg.github.io/cellxgene/posts/launch) -* [Preparing your own data](https://chanzuckerberg.github.io/cellxgene/posts/prepare) for use in cellxgene -* Checking out [our roadmap](https://chanzuckerberg.github.io/cellxgene/posts/roadmap) for future development -* [Contributing](https://chanzuckerberg.github.io/cellxgene/posts/contribute) to cellxgene + +- Seeing [what cellxgene can do](https://chanzuckerberg.github.io/cellxgene/posts/gallery) +- Learning more about cellxgene [installation](https://chanzuckerberg.github.io/cellxgene/posts/install) and [usage](https://chanzuckerberg.github.io/cellxgene/posts/launch) +- [Preparing your own data](https://chanzuckerberg.github.io/cellxgene/posts/prepare) for use in cellxgene +- Checking out [our roadmap](https://chanzuckerberg.github.io/cellxgene/posts/roadmap) for future development +- [Contributing](https://chanzuckerberg.github.io/cellxgene/posts/contribute) to cellxgene ### Quick start To install cellxgene you need Python 3.6+. We recommend [installing cellxgene into a conda or virtual environment.](https://chanzuckerberg.github.io/cellxgene/posts/install) Install the package. -``` bash + +```bash pip install cellxgene ``` Launch cellxgene with an example [anndata](https://anndata.readthedocs.io/en/latest/) file -``` bash +```bash cellxgene launch https://cellxgene-example-data.czi.technology/pbmc3k.h5ad ``` @@ -41,6 +45,17 @@ To explore more datasets already formatted for cellxgene, check out the [Demo da see [Preparing your data](https://chanzuckerberg.github.io/cellxgene/posts/prepare) to learn more about formatting your own data for cellxgene. +### Supported browsers + +cellxgene currently supports the following browsers: + +- Google Chrome 61+ +- Edge 15+ +- Firefox 60+ +- Safari 10.1+ + +Please [file an issue](https://github.com/chanzuckerberg/cellxgene/issues/new/choose) if you would like us to add support for an unsupported browser. + ### Finding help We'd love to hear from you! @@ -51,6 +66,7 @@ For any errors, [report bugs on Github](https://github.com/chanzuckerberg/cellxg # Developing with cellxgene ### Contributing + We warmly welcome contributions from the community! Please see our [contributing guide](https://chanzuckerberg.github.io/cellxgene/posts/contribute) and don't hesitate to open an issue or send a pull request to improve cellxgene. This project adheres to the Contributor Covenant [code of conduct](https://github.com/chanzuckerberg/.github/blob/master/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to opensource@chanzuckerberg.com. @@ -64,6 +80,7 @@ This project was started with the sole goal of empowering the scientific communi If you believe you have found a security issue, we would appreciate notification. Please send email to . # About + ### Core team The current core team: diff --git a/client/configuration/babel/babel.dev.js b/client/configuration/babel/babel.dev.js index 8f32d635..117f6da5 100644 --- a/client/configuration/babel/babel.dev.js +++ b/client/configuration/babel/babel.dev.js @@ -2,7 +2,14 @@ module.exports = { babelrc: false, cacheDirectory: true, presets: [ - ["modern-browsers", { loose: true, modules: false }], + [ + "@babel/preset-env", + { + useBuiltIns: "entry", + corejs: 3, + modules: false, + }, + ], "@babel/preset-react", ], plugins: [ diff --git a/client/configuration/babel/babel.prod.js b/client/configuration/babel/babel.prod.js index 604e2ef2..620cd563 100644 --- a/client/configuration/babel/babel.prod.js +++ b/client/configuration/babel/babel.prod.js @@ -1,7 +1,14 @@ module.exports = { babelrc: false, presets: [ - ["modern-browsers", { loose: true, modules: false }], + [ + "@babel/preset-env", + { + useBuiltIns: "entry", + corejs: 3, + modules: false, + }, + ], "@babel/preset-react", ], plugins: [ diff --git a/client/configuration/eslint/eslint.js b/client/configuration/eslint/eslint.js index a1189581..66637c26 100644 --- a/client/configuration/eslint/eslint.js +++ b/client/configuration/eslint/eslint.js @@ -4,9 +4,21 @@ module.exports = { extends: [ "airbnb", "plugin:eslint-comments/recommended", + "plugin:compat/recommended", "plugin:prettier/recommended", "prettier/react", ], + settings: { + polyfills: [ + "TextDecoder", + "TextEncoder", + "fetch", + "Request", + "Response", + "Headers", + "AbortController", + ], + }, env: { browser: true, commonjs: true, es6: true }, globals: { expect: true, diff --git a/client/configuration/webpack/obsoleteHTMLTemplate.html b/client/configuration/webpack/obsoleteHTMLTemplate.html new file mode 100644 index 00000000..e5c96849 --- /dev/null +++ b/client/configuration/webpack/obsoleteHTMLTemplate.html @@ -0,0 +1,81 @@ + +
+ +
+
+ Unsupported Browser +
+
+ cellxgene is currently supported on the following browsers +
+
+ + +
Chrome > 60
+
+ + +
Safari ≥ 10.1
+
+ + +
Firefox ≥ 60
+
+ + +
Edge ≥ 15
+
+
+
+
diff --git a/client/configuration/webpack/webpack.config.dev.js b/client/configuration/webpack/webpack.config.dev.js index 5175a08b..e0881c0a 100644 --- a/client/configuration/webpack/webpack.config.dev.js +++ b/client/configuration/webpack/webpack.config.dev.js @@ -1,65 +1,32 @@ -// jshint esversion: 6 const path = require("path"); const webpack = require("webpack"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const FaviconsWebpackPlugin = require("favicons-webpack-plugin"); +const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); + +const { merge } = require("webpack-merge"); + +const sharedConfig = require("./webpack.config.shared"); +const babelOptions = require("../babel/babel.dev"); -const src = path.resolve("src"); const fonts = path.resolve("src/fonts"); const nodeModules = path.resolve("node_modules"); -const babelOptions = require("../babel/babel.dev"); - -module.exports = { +const devConfig = { mode: "development", devtool: "eval", - entry: ["./src/index"], output: { - path: path.resolve("build"), pathinfo: true, filename: "static/js/bundle.js", - publicPath: "/", }, module: { rules: [ { - test: /\.js$/, - include: src, + test: /\.jsx?$/, loader: "babel-loader", options: babelOptions, }, - { - test: /\.css$/, - include: src, - exclude: [path.resolve(src, "index.css")], - loader: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - options: { - modules: { - localIdentName: "[name]__[local]___[hash:base64:5]", - }, - }, - }, - ], - }, - { - test: /index\.css$/, - include: [path.resolve(src, "index.css")], - loader: [ - { - loader: "style-loader", - }, - { - loader: "css-loader", - }, - ], - }, - - { test: /\.json$/, include: [src, nodeModules], loader: "json-loader" }, { test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2|otf)$/i, loader: "file-loader", @@ -88,6 +55,9 @@ module.exports = { }, }, }), + new MiniCssExtractPlugin({ + filename: "static/[name].css", + }), new webpack.NoEmitOnErrorsPlugin(), new webpack.DefinePlugin({ __REACT_DEVTOOLS_GLOBAL_HOOK__: "({ isDisabled: true })", @@ -97,5 +67,10 @@ module.exports = { process.env.CXG_SERVER_PORT ), }), + new ScriptExtHtmlWebpackPlugin({ + async: "obsolete", + }), ], }; + +module.exports = merge(sharedConfig, devConfig); diff --git a/client/configuration/webpack/webpack.config.prod.js b/client/configuration/webpack/webpack.config.prod.js index 0bcee9ee..a2115e7f 100644 --- a/client/configuration/webpack/webpack.config.prod.js +++ b/client/configuration/webpack/webpack.config.prod.js @@ -1,32 +1,28 @@ -// jshint esversion: 6 const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const FaviconsWebpackPlugin = require("favicons-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const TerserJSPlugin = require("terser-webpack-plugin"); const CleanCss = require("clean-css"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const FaviconsWebpackPlugin = require("favicons-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const CspHashPlugin = require("./cspHashPlugin"); - -const src = path.resolve("src"); -const fonts = path.resolve("src/fonts"); -const nodeModules = path.resolve("node_modules"); +const { merge } = require("webpack-merge"); const babelOptions = require("../babel/babel.prod"); -const publicPath = "/"; +const CspHashPlugin = require("./cspHashPlugin"); +const sharedConfig = require("./webpack.config.shared"); -module.exports = { +const fonts = path.resolve("src/fonts"); +const nodeModules = path.resolve("node_modules"); + +const prodConfig = { mode: "production", bail: true, cache: false, - entry: ["./src/index.js"], output: { filename: "static/[name]-[contenthash].js", - path: path.resolve("build"), - publicPath, }, optimization: { minimize: true, @@ -41,39 +37,10 @@ module.exports = { module: { rules: [ { - test: /\.js$/, - include: src, + test: /\.jsx?$/, loader: "babel-loader", options: babelOptions, }, - { - test: /\.css$/, - include: src, - exclude: [path.resolve(src, "index.css")], - use: [ - MiniCssExtractPlugin.loader, - { - loader: "css-loader", - options: { - modules: { - localIdentName: "[name]__[local]___[hash:base64:5]", - }, - importLoaders: 1, - }, - }, - ], - }, - { - test: /index\.css$/, - include: [path.resolve(src, "index.css")], - use: [MiniCssExtractPlugin.loader, "css-loader"], - }, - { - test: /\.json$/, - include: [src, nodeModules], - loader: "json-loader", - exclude: /manifest.json$/, - }, { test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2|otf)$/i, loader: "file-loader", @@ -121,3 +88,5 @@ module.exports = { maxAssetSize: 2000000, }, }; + +module.exports = merge(sharedConfig, prodConfig); diff --git a/client/configuration/webpack/webpack.config.shared.js b/client/configuration/webpack/webpack.config.shared.js new file mode 100644 index 00000000..2a8fcfdd --- /dev/null +++ b/client/configuration/webpack/webpack.config.shared.js @@ -0,0 +1,74 @@ +const path = require("path"); +const fs = require("fs"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const ObsoleteWebpackPlugin = require("obsolete-webpack-plugin"); +const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin"); + +const src = path.resolve("src"); +const nodeModules = path.resolve("node_modules"); + +const publicPath = "/"; + +const rawObsoleteHTMLTemplate = fs.readFileSync( + `${__dirname}/obsoleteHTMLTemplate.html`, + "utf8" +); + +const obsoleteHTMLTemplate = rawObsoleteHTMLTemplate.replace(/'/g, '"'); + +module.exports = { + entry: [ + "core-js", + "regenerator-runtime/runtime", + "fastestsmallesttextencoderdecoder", + "whatwg-fetch", + "abort-controller/polyfill", + "./src/index", + ], + output: { + path: path.resolve("build"), + publicPath, + }, + module: { + rules: [ + { + test: /\.css$/, + include: src, + exclude: [path.resolve(src, "index.css")], + use: [ + MiniCssExtractPlugin.loader, + { + loader: "css-loader", + options: { + modules: { + localIdentName: "[name]__[local]___[hash:base64:5]", + }, + importLoaders: 1, + }, + }, + ], + }, + { + test: /index\.css$/, + include: [path.resolve(src, "index.css")], + use: [MiniCssExtractPlugin.loader, "css-loader"], + }, + { + test: /\.json$/, + include: [src, nodeModules], + loader: "json-loader", + exclude: /manifest.json$/, + }, + ], + }, + plugins: [ + new ObsoleteWebpackPlugin({ + name: "obsolete", + template: obsoleteHTMLTemplate, + promptOnNonTargetBrowser: false, + }), + new ScriptExtHtmlWebpackPlugin({ + async: "obsolete", + }), + ], +}; diff --git a/client/package-lock.json b/client/package-lock.json index 545957cd..bf146854 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -4069,6 +4069,24 @@ "regenerator-runtime": "^0.13.4" } }, + "@babel/runtime-corejs2": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.10.5.tgz", + "integrity": "sha512-LJwyb1ac//Jr2zrGTTaNJhrP1wYCgVw9rzHbQPogKXCTLQ60EEWgeNtuqs6cLsq64O557SYzziCrOxNp0rRi8w==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + } + } + }, "@babel/runtime-corejs3": { "version": "7.10.5", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.5.tgz", @@ -5686,6 +5704,14 @@ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -6057,6 +6083,12 @@ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, + "ast-metadata-inferer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.4.0.tgz", + "integrity": "sha512-tKHdBe8N/Vq2nLAm4YPBVREVZjMux6KrqyPfNQgIbDl0t7HaNSmy8w4OyVHYg/cvyn5BW7o7pVwpjPte89Zhcg==", + "dev": true + }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -6944,6 +6976,12 @@ "lodash.uniq": "^4.5.0" } }, + "caniuse-db": { + "version": "1.0.30001107", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001107.tgz", + "integrity": "sha512-ffbV17yvEamsNm4N4dDDHdj147tWwdKw+mGyeOmvQcnu+gu455xUg8degvUOCB+fIAm7Rv3gXVn7XlTiYKymMQ==", + "dev": true + }, "caniuse-lite": { "version": "1.0.30001039", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz", @@ -7725,10 +7763,9 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" }, "core-js-compat": { "version": "3.6.5", @@ -9448,6 +9485,94 @@ } } }, + "eslint-plugin-compat": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.8.0.tgz", + "integrity": "sha512-5CuWUSZXZkXLCQJBriEpndn/YWrvggDSHTpRJq++kR8GVcsWbTdp8Eh+nBA7JlrNi7ZJ/+kniOVXmn3bpnxuRA==", + "dev": true, + "requires": { + "ast-metadata-inferer": "^0.4.0", + "browserslist": "^4.12.2", + "caniuse-db": "^1.0.30001090", + "core-js": "^3.6.5", + "find-up": "^4.1.0", + "lodash.memoize": "4.1.2", + "mdn-browser-compat-data": "^1.0.28", + "semver": "7.3.2" + }, + "dependencies": { + "browserslist": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz", + "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001093", + "electron-to-chromium": "^1.3.488", + "escalade": "^3.0.1", + "node-releases": "^1.1.58" + } + }, + "caniuse-lite": { + "version": "1.0.30001107", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001107.tgz", + "integrity": "sha512-86rCH+G8onCmdN4VZzJet5uPELII59cUzDphko3thQFgAQG1RNa+sVLDoALIhRYmflo5iSIzWY3vu1XTWtNMQQ==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.510", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.510.tgz", + "integrity": "sha512-sLtGB0znXdmo6lM8hy5wTVo+fLqvIuO8hEpgc0DvPmFZqvBu/WB7AarEwhxVKjf3rVbws/rC8Xf+AlsOb36lJQ==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "node-releases": { + "version": "1.1.60", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", + "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==", + "dev": true + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "eslint-plugin-eslint-comments": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", @@ -9716,6 +9841,11 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, "events": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", @@ -10067,6 +10197,11 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fastestsmallesttextencoderdecoder": { + "version": "1.0.22", + "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==" + }, "favicons": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/favicons/-/favicons-5.5.0.tgz", @@ -13886,6 +14021,15 @@ "safe-buffer": "^5.1.2" } }, + "mdn-browser-compat-data": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/mdn-browser-compat-data/-/mdn-browser-compat-data-1.0.32.tgz", + "integrity": "sha512-dqIstpk2ysqa6XcI8/fz1yB6bOKrIs61RIEE00Dj7+WHReXlGrCIiol1NBPsLUNE+HC/4y2f8va8vy1WsiCkAQ==", + "dev": true, + "requires": { + "extend": "3.0.2" + } + }, "mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", @@ -14769,6 +14913,26 @@ "has": "^1.0.3" } }, + "obsolete-web": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/obsolete-web/-/obsolete-web-0.5.6.tgz", + "integrity": "sha512-rrs7kSJxOVFvvY7wuCfjg/ngXbO6q1m7Llq30RaN9WYIDH1zAoA1xWLIY39D3e5967g/NeCasI/o8ojhMMkaaA==", + "dev": true, + "requires": { + "@babel/runtime-corejs2": "^7.0.0" + } + }, + "obsolete-webpack-plugin": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/obsolete-webpack-plugin/-/obsolete-webpack-plugin-0.5.6.tgz", + "integrity": "sha512-oKlRW4ycxJfF/mojtpGuQwaP+J4JwIgjFuFnMgURB6AaKxAVaRwiO0oWhqYjwwJ5LxhVybOl+CnGAlhHBHBdEQ==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "obsolete-web": "^0.5.6", + "webpack-sources": "^1.0.0" + } + }, "omggif": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", @@ -16491,9 +16655,9 @@ } }, "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, "regenerator-transform": { "version": "0.14.5", @@ -17147,6 +17311,14 @@ "ajv-keywords": "^3.1.0" } }, + "script-ext-html-webpack-plugin": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/script-ext-html-webpack-plugin/-/script-ext-html-webpack-plugin-2.1.4.tgz", + "integrity": "sha512-7MAv3paAMfh9y2Rg+yQKp9jEGC5cEcmdge4EomRqri10qoczmliYEVPVNz0/5e9QQ202e05qDll9B8zZlY9N1g==", + "requires": { + "debug": "^4.1.1" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -19513,6 +19685,14 @@ "minimist": "^1.2.0", "request": "^2.88.0", "rx": "^4.1.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + } } }, "wait-port": { @@ -20168,6 +20348,35 @@ "uuid": "^3.3.2" } }, + "webpack-merge": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.0.9.tgz", + "integrity": "sha512-P4teh6O26xIDPugOGX61wPxaeP918QOMjmzhu54zTVcLtOS28ffPWtnv+ilt3wscwBUCL2WNMnh97XkrKqt9Fw==", + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "dependencies": { + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "requires": { + "kind-of": "^6.0.2" + } + } + } + }, "webpack-sources": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", @@ -20194,6 +20403,11 @@ "iconv-lite": "0.4.24" } }, + "whatwg-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.2.0.tgz", + "integrity": "sha512-SdGPoQMMnzVYThUbSrEvqTlkvC1Ux27NehaJ/GUHBfNrh5Mjg+1/uRyFMwVnxO2MrikMWvWAqUGgQOfVU4hT7w==" + }, "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", @@ -20319,6 +20533,11 @@ } } }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/client/package.json b/client/package.json index 094e62f6..9c247eea 100644 --- a/client/package.json +++ b/client/package.json @@ -29,12 +29,23 @@ "resolutions": { "eslint-scope": "3.7.1" }, + "browserslist": [ + "Chrome > 60", + "Safari >= 10.1", + "iOS >= 10.3", + "Firefox >= 60", + "Edge >= 15", + "not Explorer > 0" + ], "dependencies": { "@blueprintjs/core": "^3.30.0", "@blueprintjs/icons": "^3.19.0", "@blueprintjs/select": "^3.13.5", + "abort-controller": "^3.0.0", + "core-js": "^3.6.5", "d3": "^4.10.0", "d3-scale-chromatic": "^1.5.0", + "fastestsmallesttextencoderdecoder": "^1.0.22", "flatbuffers": "^1.11.0", "fuzzysort": "^1.1.4", "gl-mat4": "^1.2.0", @@ -52,8 +63,12 @@ "react-redux": "^7.2.0", "redux": "^4.0.5", "redux-thunk": "^2.3.0", + "regenerator-runtime": "^0.13.7", "regl": "^1.6.1", - "tinyqueue": "^2.0.3" + "script-ext-html-webpack-plugin": "^2.1.4", + "tinyqueue": "^2.0.3", + "webpack-merge": "^5.0.9", + "whatwg-fetch": "^3.2.0" }, "devDependencies": { "@babel/core": "^7.10.5", @@ -85,6 +100,7 @@ "eslint-config-airbnb": "^18.2.0", "eslint-config-prettier": "^6.11.0", "eslint-loader": "^3.0.4", + "eslint-plugin-compat": "^3.8.0", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-filenames": "^1.3.2", "eslint-plugin-import": "^2.22.0", @@ -107,6 +123,7 @@ "json-loader": "^0.5.7", "lint-staged": "^10.2.11", "mini-css-extract-plugin": "^0.9.0", + "obsolete-webpack-plugin": "^0.5.6", "optimize-css-assets-webpack-plugin": "^5.0.3", "prettier": "^2.0.5", "puppeteer": "^3.3.0", diff --git a/client/src/index.js b/client/src/index.js index 7f2de221..163f8abc 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -1,4 +1,3 @@ -// jshint esversion: 6 import React from "react"; import ReactDOM from "react-dom"; import { Provider } from "react-redux"; diff --git a/client/src/util/stateManager/matrix.js b/client/src/util/stateManager/matrix.js index 05d4e61d..e9a1e445 100644 --- a/client/src/util/stateManager/matrix.js +++ b/client/src/util/stateManager/matrix.js @@ -170,11 +170,11 @@ export function encodeMatrixFBS(df) { function promoteTypedArray(o) { /* - Decide what internal data type to use for the data returned from + Decide what internal data type to use for the data returned from the server. TODO - future optimization: not all int32/uint32 data series require - promotion to float64. We COULD simply look at the data to decide. + promotion to float64. We COULD simply look at the data to decide. */ if (isFpTypedArray(o) || Array.isArray(o)) return o;