diff --git a/.eslintrc b/.eslintrc index 81a3f66..b9b8fc1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,25 +1,44 @@ { - "parser": "babel-eslint", - "parserOptions": { - "sourceType": "module" - }, "env": { - "browser": true, - "es6": true, - "node": true + "browser": true, + "es6": true, + "node": true + }, + "extends": [ + "airbnb", + "prettier", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:prettier/recommended" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module" }, - "extends": ["airbnb", "prettier"], - "plugins": ["prettier"], + "plugins": [ + "react", + "@typescript-eslint", + "prettier" + ], "rules": { "prettier/prettier": ["error"], "import/no-extraneous-dependencies": 0, - "react/jsx-filename-extension": 0 + "react/jsx-filename-extension": 0, + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" }, "settings": { "import/resolver": { + "node": { + "paths": ["src"], + "extensions": [".ts", ".tsx", ".js", ".jsx"] + }, "webpack": { "config": "./build-utils/webpack.common.js" } } } -} +} \ No newline at end of file diff --git a/build-utils/webpack.common.js b/build-utils/webpack.common.js index ad141ab..89f46fb 100644 --- a/build-utils/webpack.common.js +++ b/build-utils/webpack.common.js @@ -8,13 +8,19 @@ const APP_DIR = path.resolve(__dirname, '..', './src'); const NODE_MODULES = path.resolve(__dirname, '..', './node_modules'); module.exports = { - entry: './src/index.js', + entry: './src/index.tsx', module: { rules: [ { - test: /\.(config\.js|js|jsx)$/, + test: /\.(config\.js|(t|j)s|(t|j)sx)$/, exclude: /node_modules/, - use: ['babel-loader'], + use: ['ts-loader'], + }, + { + enforce: 'pre', + test: /\.js$/, + exclude: /node_modules/, + loader: 'source-map-loader', }, { test: /\.(woff|woff2)$/, @@ -52,18 +58,23 @@ module.exports = { }, ], }, + devtool: 'source-map', resolve: { - extensions: ['*', '.js', '.jsx'], + extensions: ['*', '.ts', '.tsx', '.js', '.jsx'], + modules: [ + path.resolve(__dirname, '..', 'src'), + path.resolve(__dirname, '..', 'node_modules'), + ], alias: { - features: path.resolve(__dirname, '..', 'src', 'features'), - components: path.resolve(__dirname, '..', 'src', 'components'), - themes: path.resolve(__dirname, '..', 'src', 'themes'), - lib: path.resolve(__dirname, '..', 'src', 'lib'), - pages: path.resolve(__dirname, '..', 'src', 'pages'), - api: path.resolve(__dirname, '..', 'src', 'api'), - constants: path.resolve(__dirname, '..', 'src', 'constants'), - assets: path.resolve(__dirname, '..', 'src', 'assets'), - '@': path.resolve(__dirname, '..', 'src'), + // features: path.resolve(__dirname, '..', 'src', 'features'), + // components: path.resolve(__dirname, '..', 'src', 'components'), + // themes: path.resolve(__dirname, '..', 'src', 'themes'), + // lib: path.resolve(__dirname, '..', 'src', 'lib'), + // pages: path.resolve(__dirname, '..', 'src', 'pages'), + // api: path.resolve(__dirname, '..', 'src', 'api'), + // constants: path.resolve(__dirname, '..', 'src', 'constants'), + // assets: path.resolve(__dirname, '..', 'src', 'assets'), + // '@': path.resolve(__dirname, '..', 'src'), }, }, plugins: [ diff --git a/package-lock.json b/package-lock.json index 088c919..d87c435 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1226,6 +1226,16 @@ "regenerator-runtime": "^0.13.2" } }, + "@babel/runtime-corejs3": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.2.tgz", + "integrity": "sha512-+a2M/u7r15o3dV1NEizr9bRi+KUVnrs/qYxF0Z06DAPx/4VCWaz1WA7EcbE+uqGgt39lp5akWGmHsTseIkHkHg==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, "@babel/template": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", @@ -1318,9 +1328,9 @@ } }, "@fortawesome/react-fontawesome": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.9.tgz", - "integrity": "sha512-49V3WNysLZU5fZ3sqSuys4nGRytsrxJktbv3vuaXkEoxv22C6T7TEG0TW6+nqVjMnkfCQd5xOnmJoZHMF78tOw==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.10.tgz", + "integrity": "sha512-UGdpJiLBIqR/8xcLrCarf2pChqQFKjDTD02C7ZS/odpOVVl2YuHYRCLEOQ0GpfOk6jtYhmouSFOFoC8qNCe5cg==", "requires": { "prop-types": "^15.7.2" } @@ -1373,6 +1383,12 @@ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -1390,6 +1406,12 @@ "@types/node": "*" } }, + "@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "dev": true + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -1408,14 +1430,39 @@ "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/react": { - "version": "16.9.31", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.31.tgz", - "integrity": "sha512-NpYJpNMWScFXtx3A2BJMeew2G3+9SEslVWMdxNJ6DLvxIuxWjY1bizK9q5Y1ujhln31vtjmhjOAYDr9Xx3k9FQ==", + "version": "16.9.35", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.35.tgz", + "integrity": "sha512-q0n0SsWcGc8nDqH2GJfWQWUOmZSJhXV64CjVN5SvcNti3TdEaA3AH0D8DwNmMdzjMAC/78tB8nAZIlV8yTz+zQ==", "requires": { "@types/prop-types": "*", "csstype": "^2.2.0" } }, + "@types/react-dom": { + "version": "16.9.8", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz", + "integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==", + "requires": { + "@types/react": "*" + } + }, + "@types/react-fontawesome": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@types/react-fontawesome/-/react-fontawesome-1.6.4.tgz", + "integrity": "sha512-/fHr+BoUX+3MYpCkb8a+Bpt+Je2/0FgFi1XSaHH0ga1hqMy5PS7Ny/XV0Qh5cJHeKvkONbKWPSwgPlqK7UtdqA==", + "requires": { + "@types/react": "*" + } + }, + "@types/simple-peer": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@types/simple-peer/-/simple-peer-9.6.0.tgz", + "integrity": "sha512-X2y6s+vE/3j03hkI90oqld2JH2J/m1L7yFCYYPyFV/whrOK1h4neYvJL3GIE+UcACJacXZqzdmDKudwec18RbA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/tapable": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.4.tgz", @@ -1460,6 +1507,136 @@ } } }, + "@typescript-eslint/eslint-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.2.0.tgz", + "integrity": "sha512-t9RTk/GyYilIXt6BmZurhBzuMT9kLKw3fQoJtK9ayv0tXTlznXEAnx07sCLXdkN3/tZDep1s1CEV95CWuARYWA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "3.2.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "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 + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.2.0.tgz", + "integrity": "sha512-UbJBsk+xO9dIFKtj16+m42EvUvsjZbbgQ2O5xSTSfVT1Z3yGkL90DVu0Hd3029FZ5/uBgl+F3Vo8FAcEcqc6aQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.2.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.2.0.tgz", + "integrity": "sha512-Vhu+wwdevDLVDjK1lIcoD6ZbuOa93fzqszkaO3iCnmrScmKwyW/AGkzc2UvfE5TCoCXqq7Jyt6SOXjsIlpqF4A==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "3.2.0", + "@typescript-eslint/typescript-estree": "3.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.2.0.tgz", + "integrity": "sha512-uh+Y2QO7dxNrdLw7mVnjUqkwO/InxEqwN0wF+Za6eo3coxls9aH9kQ/5rSvW2GcNanebRTmsT5w1/92lAOb1bA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "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 + } + } + }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", @@ -1648,6 +1825,12 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -2921,6 +3104,12 @@ } } }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -3133,6 +3322,17 @@ "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", "dev": true }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", @@ -4012,22 +4212,35 @@ } }, "eslint-plugin-react": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.16.0.tgz", - "integrity": "sha512-GacBAATewhhptbK3/vTP09CbFrgUJmBSaaRcWdbQLFvUZy9yVcQxigBNHGPU/KE2AyHpzj3AWXpxoMTsIDiHug==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.0.tgz", + "integrity": "sha512-rqe1abd0vxMjmbPngo4NaYxTcR3Y4Hrmc/jg4T+sYz63yqlmJRknpEQfmWY+eDWPuMmix6iUIK+mv0zExjeLgA==", "dev": true, "requires": { - "array-includes": "^3.0.3", + "array-includes": "^3.1.1", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.2.1", - "object.entries": "^1.1.0", - "object.fromentries": "^2.0.0", - "object.values": "^1.1.0", + "jsx-ast-utils": "^2.2.3", + "object.entries": "^1.1.1", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.12.0" + "resolve": "^1.15.1", + "string.prototype.matchall": "^4.0.2", + "xregexp": "^4.3.0" }, "dependencies": { + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -4037,10 +4250,94 @@ "esutils": "^2.0.2" } }, + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "jsx-ast-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.3.0.tgz", + "integrity": "sha512-3HNoc7nZ1hpZIKB3hJ7BlFRkzCx2BynRtfSwbkqZdpRdvAPsGMnzclPwrvDBS7/lalHTj21NwIeaEpysHBOudg==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "object.assign": "^4.1.0" + } + }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -5931,6 +6228,70 @@ "ipaddr.js": "^1.9.0" } }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "interpret": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", @@ -6186,6 +6547,12 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-symbol": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", @@ -6400,9 +6767,12 @@ } }, "lib0": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.0.5.tgz", - "integrity": "sha512-3ElV6/t5Lv0Eczlnh/05q+Uq3RxQ/Q0zdN6LVtaUERQIDDZsP/CUXEGLsV8KZTgZwVFNCPGXNWYE+3WTOo+SHw==" + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.28.tgz", + "integrity": "sha512-3gB5Ow5B/iL5jSEDgNIlkylX5loHrGeTajZXcCFEE8svVhYBVAn9Rt0uw+86bpbw64tFN8gkZ+BSivv8C0ZWdQ==", + "requires": { + "isomorphic.js": "^0.1.3" + } }, "load-json-file": { "version": "2.0.0", @@ -6518,6 +6888,12 @@ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, "lodash.trim": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz", @@ -7081,9 +7457,9 @@ "dev": true }, "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", "dev": true }, "object-is": { @@ -7132,33 +7508,66 @@ } }, "object.fromentries": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.1.tgz", - "integrity": "sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", + "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.15.0", + "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" }, "dependencies": { "es-abstract": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", - "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==", + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", "dev": true, "requires": { - "es-to-primitive": "^1.2.0", + "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.0", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" } } } @@ -7515,6 +7924,12 @@ "sha.js": "^2.4.8" } }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -7833,9 +8248,9 @@ "dev": true }, "prettier": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", - "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true }, "prettier-linter-helpers": { @@ -8995,26 +9410,89 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "simple-peer": { - "version": "9.6.2", - "resolved": "https://registry.npmjs.org/simple-peer/-/simple-peer-9.6.2.tgz", - "integrity": "sha512-EOKoImCaqtNvXIntxT1CBBK/3pVi7tMAoJ3shdyd9qk3zLm3QPiRLb/sPC1G2xvKJkJc5fkQjCXqRZ0AknwTig==", + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, "requires": { - "debug": "^4.0.1", - "get-browser-rtc": "^1.0.0", - "queue-microtask": "^1.1.0", - "randombytes": "^2.0.3", - "readable-stream": "^3.4.0" + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" }, "dependencies": { - "debug": { - "version": "4.1.1", + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-peer": { + "version": "9.6.2", + "resolved": "https://registry.npmjs.org/simple-peer/-/simple-peer-9.6.2.tgz", + "integrity": "sha512-EOKoImCaqtNvXIntxT1CBBK/3pVi7tMAoJ3shdyd9qk3zLm3QPiRLb/sPC1G2xvKJkJc5fkQjCXqRZ0AknwTig==", + "requires": { + "debug": "^4.0.1", + "get-browser-rtc": "^1.0.0", + "queue-microtask": "^1.1.0", + "randombytes": "^2.0.3", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { @@ -9225,6 +9703,97 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, + "source-map-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-1.0.0.tgz", + "integrity": "sha512-ZayyQCSCrQazN50aCvuS84lJT4xc1ZAcykH5blHaBdVveSwjiFK8UGMPvao0ho54DTb0Jf7m57uRRG/YYUZ2Fg==", + "dev": true, + "requires": { + "data-urls": "^2.0.0", + "iconv-lite": "^0.5.1", + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.6", + "source-map": "^0.6.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "iconv-lite": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", + "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", @@ -9466,24 +10035,335 @@ "strip-ansi": "^4.0.0" } }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", "dev": true, "requires": { "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } } }, "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", "dev": true, "requires": { "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } } }, "string_decoder": { @@ -9808,18 +10688,120 @@ "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", "dev": true }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", "dev": true }, + "ts-loader": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz", + "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "ttf-loader": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/ttf-loader/-/ttf-loader-1.0.2.tgz", @@ -9882,6 +10864,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typescript": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", + "dev": true + }, "ua-parser-js": { "version": "0.7.20", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", @@ -10291,6 +11279,12 @@ "minimalistic-assert": "^1.0.0" } }, + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + }, "webpack": { "version": "4.41.2", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", @@ -10751,6 +11745,23 @@ "integrity": "sha1-DjaExsuZlbQ+/J3wPkw2XZX9nMA=", "dev": true }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^5.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -10844,6 +11855,15 @@ "async-limiter": "~1.0.0" } }, + "xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "dev": true, + "requires": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -10866,6 +11886,13 @@ "integrity": "sha512-TUUPZe1tk2chcN61BbOcNh8e8Dk0wVL/rM2qA0Wc6Fr4io+oByO1SsVHLnmMgzVwi+mZvGTIRzqZP0nA+en31w==", "requires": { "lib0": "0.0.5" + }, + "dependencies": { + "lib0": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.0.5.tgz", + "integrity": "sha512-3ElV6/t5Lv0Eczlnh/05q+Uq3RxQ/Q0zdN6LVtaUERQIDDZsP/CUXEGLsV8KZTgZwVFNCPGXNWYE+3WTOo+SHw==" + } } }, "y-protocols": { diff --git a/package.json b/package.json index 17040fc..bd0de79 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "codeinterview-frontend", "version": "1.0.0", "description": "", - "main": "index.js", + "main": "index.tsx", "scripts": { "start": "webpack-dev-server --config build-utils/webpack.config.js --env.env=dev", "build": "webpack --config build-utils/webpack.config.js --env.env=prod", @@ -20,6 +20,9 @@ "@babel/plugin-transform-runtime": "^7.9.0", "@babel/preset-env": "^7.6.3", "@babel/preset-react": "^7.6.3", + "@types/simple-peer": "^9.6.0", + "@typescript-eslint/eslint-plugin": "^3.2.0", + "@typescript-eslint/parser": "^3.2.0", "babel-eslint": "^10.0.3", "babel-loader": "^8.0.6", "clean-webpack-plugin": "^3.0.0", @@ -33,7 +36,7 @@ "eslint-plugin-import": "^2.18.2", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-prettier": "^3.1.1", - "eslint-plugin-react": "^7.16.0", + "eslint-plugin-react": "^7.20.0", "file-loader": "^6.0.0", "html-webpack-plugin": "^3.2.0", "postcss-import": "^12.0.1", @@ -42,11 +45,14 @@ "postcss-loader": "^3.0.0", "postcss-nested": "^4.2.1", "postcss-simple-vars": "^5.0.2", - "prettier": "^1.18.2", + "prettier": "^1.19.1", "react-hot-loader": "^4.12.15", + "source-map-loader": "^1.0.0", "style-loader": "^1.1.3", "sugarss": "^2.0.0", + "ts-loader": "^7.0.5", "ttf-loader": "^1.0.2", + "typescript": "^3.9.5", "url-loader": "^4.0.0", "webpack": "^4.41.2", "webpack-bundle-analyzer": "^3.6.0", @@ -58,11 +64,15 @@ "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.28", "@fortawesome/free-solid-svg-icons": "^5.13.0", - "@fortawesome/react-fontawesome": "^0.1.9", + "@fortawesome/react-fontawesome": "^0.1.10", "@reduxjs/toolkit": "^1.3.2", + "@types/react": "^16.9.35", + "@types/react-dom": "^16.9.8", + "@types/react-fontawesome": "^1.6.4", "axios": "^0.19.2", "bootstrap": "^4.4.1", "chalk": "^4.0.0", + "lib0": "^0.2.28", "moment": "^2.24.0", "monaco-editor-webpack-plugin": "^1.9.0", "overlayscrollbars": "^1.12.0", diff --git a/src/components/control-bar/control-bar.jsx b/src/components/control-bar/control-bar.tsx similarity index 51% rename from src/components/control-bar/control-bar.jsx rename to src/components/control-bar/control-bar.tsx index 55e63aa..233ecc9 100644 --- a/src/components/control-bar/control-bar.jsx +++ b/src/components/control-bar/control-bar.tsx @@ -1,14 +1,13 @@ import React from 'react'; -import PropTypes from 'prop-types'; import './control-bar.css'; -const controlBar = ({ children }) => { - return
{children}
; -}; +interface Props { + children: React.ReactNode; +} -controlBar.propTypes = { - children: PropTypes.node.isRequired, -}; +function controlBar({ children }: Props): React.ReactElement { + return
{children}
; +} export default controlBar; diff --git a/src/components/editor-dropdown/editor-dropdown.jsx b/src/components/editor-dropdown/editor-dropdown.tsx similarity index 59% rename from src/components/editor-dropdown/editor-dropdown.jsx rename to src/components/editor-dropdown/editor-dropdown.tsx index ca69dd0..a560a2f 100644 --- a/src/components/editor-dropdown/editor-dropdown.jsx +++ b/src/components/editor-dropdown/editor-dropdown.tsx @@ -1,8 +1,17 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { Dropdown, DropdownButton } from 'react-bootstrap'; -const editorDropdown = ({ defaultItem, items, handler }) => { +interface Props { + defaultItem: string; + items: string[]; + handler: (e: React.MouseEvent, item: string) => void; +} + +function editorDropdown({ + defaultItem, + items, + handler, +}: Props): React.ReactElement { return ( { size="sm" variant="dark" > - {items.map(item => { + {items.map((item: string) => { return ( handler(e, item)} + onClick={(e: React.MouseEvent) => handler(e, item)} > {item} @@ -25,12 +34,6 @@ const editorDropdown = ({ defaultItem, items, handler }) => { })} ); -}; - -editorDropdown.propTypes = { - defaultItem: PropTypes.string.isRequired, - items: PropTypes.arrayOf(PropTypes.string).isRequired, - handler: PropTypes.func.isRequired, -}; +} export default editorDropdown; diff --git a/src/components/video-player/video-player.jsx b/src/components/video-player/video-player.tsx similarity index 64% rename from src/components/video-player/video-player.jsx rename to src/components/video-player/video-player.tsx index 03f110d..c0e247e 100644 --- a/src/components/video-player/video-player.jsx +++ b/src/components/video-player/video-player.tsx @@ -1,6 +1,5 @@ /* eslint-disable jsx-a11y/media-has-caption */ import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faMicrophone, @@ -9,29 +8,46 @@ import { import './video-player.css'; -function connectVideoToStream(video, stream) { +function connectVideoToStream( + video: HTMLVideoElement, + stream: MediaStream +) { // eslint-disable-next-line no-param-reassign if (stream) video.srcObject = stream; } -const Player = ({ +interface Props { + stream: MediaStream; + width: any; + className: string; + onClick?: ( + event: React.MouseEvent + ) => void; + showControls: Boolean; + name: string; +} + +function Player({ stream, width, className, onClick, showControls, name, -}) => { - const [isMuted, setMuted] = useState(false); - const videoRef = React.createRef(); +}: Props): React.ReactElement { + const [isMuted, setMuted] = useState(false); + const videoRef: React.RefObject = React.createRef(); useEffect(() => { - connectVideoToStream(videoRef.current, stream); + if (videoRef.current) + connectVideoToStream(videoRef.current, stream); }, [stream]); const toggleAudio = () => { - videoRef.current.muted = !isMuted; - setMuted(!isMuted); + if (videoRef.current) { + videoRef.current.muted = !isMuted; + setMuted(!isMuted); + } }; if (stream) { @@ -58,23 +74,6 @@ const Player = ({ ); } return
; -}; - -Player.defaultProps = { - stream: null, - width: '100%', - className: '', - onClick: () => null, - showControls: false, - name: '', -}; -Player.propTypes = { - stream: PropTypes.shape({}), - width: PropTypes.string, - className: PropTypes.string, - onClick: PropTypes.func, - showControls: PropTypes.bool, - name: PropTypes.string, -}; +} export default Player; diff --git a/src/features/shared-monaco-editor/shared-monaco-editor.jsx b/src/features/shared-monaco-editor/shared-monaco-editor.jsx index 075a117..3cfaba0 100644 --- a/src/features/shared-monaco-editor/shared-monaco-editor.jsx +++ b/src/features/shared-monaco-editor/shared-monaco-editor.jsx @@ -6,12 +6,12 @@ import PropTypes from 'prop-types'; import { Row, Col } from 'react-bootstrap'; import MonacoEditor from 'react-monaco-editor'; import { MonacoBinding } from 'y-monaco'; -import EditorDropdown from 'components/editor-dropdown/editor-dropdown'; import { toast } from 'react-toastify'; import LANG_CONFIG from 'constants/languages'; import langService from 'api/http/lang-service'; import loadingIcon from 'assets/svg/editor-loading.svg'; +import EditorDropdown from 'components/editor-dropdown/editor-dropdown'; import setDefaultTheme from './theme-utils'; import defaultConfig from './default-config'; diff --git a/src/features/terminal/log-renderer.js b/src/features/terminal/log-renderer.ts similarity index 77% rename from src/features/terminal/log-renderer.js rename to src/features/terminal/log-renderer.ts index 232c324..904ef43 100644 --- a/src/features/terminal/log-renderer.js +++ b/src/features/terminal/log-renderer.ts @@ -11,22 +11,45 @@ const ENTRY_TYPES = { CODE_OUTPUT: 'CO', }; -class LogRenderer { - constructor({ showTimestamps, profiles }) { +interface Config { + showTimestamps: boolean; + profiles: Profile[]; +} + +interface ILogRenderer { + readonly chalk: chalk.Chalk; + showTimestamps: boolean; + profiles: Profile[]; +} + +class LogRenderer implements ILogRenderer { + chalk: chalk.Chalk; + + showTimestamps: boolean; + + profiles: Profile[]; + + constructor({ showTimestamps, profiles }: Config) { this.chalk = new chalk.Instance({ level: 3 }); this.showTimestamps = showTimestamps; this.profiles = profiles; } - colorAuthor(username) { + colorAuthor(username: string): string { const profiles = this.profiles.filter( - profile => profile.username === username + (profile: Profile) => profile.username === username ); if (profiles.length === 0) return this.chalk`{dim ${username}}`; return this.chalk`{hex('${profiles[0].color}') ${username}}`; } - withTimestamp({ timestamp, line }) { + withTimestamp({ + timestamp, + line, + }: { + timestamp: number; + line: string; + }): string { if (this.showTimestamps) { const ts = this.chalk`{dim ${moment .unix(timestamp) @@ -36,8 +59,18 @@ class LogRenderer { return line; } - render({ timestamp, content, type, author }) { - const rv = []; + render({ + timestamp, + content, + type, + author, + }: { + timestamp: number; + content: any; + type: string; + author: string; + }): string[] { + const rv: string[] = []; const add = line => { rv.push(this.withTimestamp({ timestamp, line })); diff --git a/src/features/terminal/terminal.jsx b/src/features/terminal/terminal.tsx similarity index 66% rename from src/features/terminal/terminal.jsx rename to src/features/terminal/terminal.tsx index a503bb4..5f8cc2a 100644 --- a/src/features/terminal/terminal.jsx +++ b/src/features/terminal/terminal.tsx @@ -1,5 +1,4 @@ -import React, { useEffect } from 'react'; -import PropTypes from 'prop-types'; +import React, { useEffect, useRef } from 'react'; import { Row } from 'react-bootstrap'; import { Terminal as Xterm } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; @@ -9,49 +8,60 @@ import LogRenderer from './log-renderer'; import 'xterm/css/xterm.css'; import './terminal.css'; -const xtermRef = React.createRef(); -const inputRef = React.createRef(); -const logRenderer = new LogRenderer({ +const logRenderer: LogRenderer = new LogRenderer({ showTimestamps: false, + profiles: [], }); const addons = { fitAddon: new FitAddon(), }; -let xterm = null; -let prevLogs = []; +let xterm: Xterm; +let prevLogs: any[] = []; + +interface Props { + logs: any[]; + profiles: Profile[]; + options: {}; + onInput: (data: string) => void; + className: string; + name: string; +} -const Terminal = ({ +function Terminal({ logs, profiles, options, onInput, className, name, -}) => { +}: Props): React.ReactElement { + const xtermRef: React.RefObject = useRef(null); + const inputRef: React.RefObject = useRef(null); + // Terminal helpers - const clear = () => { + function clear(): void { // https://github.com/xtermjs/xterm.js/issues/950 // When run initially at mount stage, xterm.clear() doesn't work since all the // content could still be in the write buffer and not rendered. xterm.reset() // doesn't seem to work either. xterm.write('\x1b[H\x1b[2J'); - }; + } - const writeEntry = log => { + function writeEntry(log: any): void { const lines = logRenderer.render(log); lines.forEach(line => { xterm.writeln(line); }); - }; + } - const writeLogs = (update = false) => { + function writeLogs(update: boolean = false): void { if (!update) clear(); logs.forEach(log => { // TODO: this check is inefficient. Maintain a hashmap instead. if (!update || prevLogs.indexOf(log) === -1) writeEntry(log); }); - }; + } useEffect(() => { window.addEventListener('resize', () => addons.fitAddon.fit()); @@ -67,17 +77,19 @@ const Terminal = ({ ...options, }); xterm.loadAddon(addons.fitAddon); - xterm.open(xtermRef.current); - xterm.inputBuffer = []; + if (xtermRef.current) xterm.open(xtermRef.current); addons.fitAddon.fit(); // Accept user input (chat) - inputRef.current.addEventListener('keydown', e => { - if (e.keyCode === 13) { - if (onInput) onInput(inputRef.current.value); - inputRef.current.value = ''; - } - }); + if (inputRef && inputRef.current) { + inputRef.current.addEventListener('keydown', e => { + if (e.keyCode === 13) { + if (onInput) onInput(inputRef?.current?.value || ''); + if (inputRef && inputRef.current) + inputRef.current.value = ''; + } + }); + } }, []); useEffect(() => { @@ -103,27 +115,6 @@ const Terminal = ({
); -}; - -Terminal.defaultProps = { - profiles: [], - options: {}, - onInput: () => {}, - className: '', - name: 'Log Terminal', -}; -Terminal.propTypes = { - profiles: PropTypes.arrayOf( - PropTypes.shape({ - username: PropTypes.string, - color: PropTypes.string, - }) - ), - options: PropTypes.shape({}), - onInput: PropTypes.func, - logs: PropTypes.arrayOf(PropTypes.shape({})).isRequired, - className: PropTypes.string, - name: PropTypes.string, -}; +} export default Terminal; diff --git a/src/features/video-chat/video-chat.css b/src/features/video-chat/video-chat.css index b508b90..1b32fe9 100644 --- a/src/features/video-chat/video-chat.css +++ b/src/features/video-chat/video-chat.css @@ -70,6 +70,10 @@ $compressed-window-width: 250px; max-height: calc($compressed-window-height - $title-bar-height); max-width: $compressed-window-width; } + .peer-stream, .focus-stream { + max-height: 18vh; + width: auto !important; + } } } diff --git a/src/features/video-chat/video-chat.jsx b/src/features/video-chat/video-chat.tsx similarity index 74% rename from src/features/video-chat/video-chat.jsx rename to src/features/video-chat/video-chat.tsx index ec39bac..edb4c2b 100644 --- a/src/features/video-chat/video-chat.jsx +++ b/src/features/video-chat/video-chat.tsx @@ -13,7 +13,7 @@ import Player from 'components/video-player/video-player'; import './video-chat.css'; -function getName(peerId) { +function getName(peerId: string): string { const { sync } = window; if (peerId in sync.profiles) { return sync.profiles[peerId].username; @@ -21,52 +21,69 @@ function getName(peerId) { return ''; } -const VideoChat = () => { - const [myPeerId, setMyPeerId] = useState( - window.sync?.peerId || null +function VideoChat(): React.ReactElement { + const [myPeerId, setMyPeerId] = useState( + window.sync?.peerId || null! ); - const [streams, setStreams] = useState(window.sync?.streams || {}); - const [localStream, setLocalStream] = useState(null); - const [focusStream, setFocusStream] = useState(null); - const [focusId, setFocusId] = useState(null); - const [uiCompressed, setUiCompressed] = useState(false); - const [uiMinimized, setUiMinimized] = useState(false); + const [streams, setStreams] = useState<{ + [peerId: string]: MediaStream; + }>(window.sync?.streams || null!); + const [localStream, setLocalStream] = useState(null!); + const [focusStream, setFocusStream] = useState(null!); + const [focusId, setFocusId] = useState(); + const [uiCompressed, setUiCompressed] = useState(false); + const [uiMinimized, setUiMinimized] = useState(false); // Media stream helper - const getMediaStream = () => { + function getMediaStream(): void { window.sync .getUserMedia() - .then(stream => { + .then((stream: MediaStream) => { // don't want our audio echo setLocalStream(new MediaStream(stream.getVideoTracks())); }) .catch(console.warn); - }; + } // Sync listeners - const addStream = ({ peerId, stream }) => { + function addStream({ + peerId, + stream, + }: { + peerId: string; + stream: MediaStream; + }): void { setStreams({ ...streams, [peerId]: stream, }); - }; + } - const updatePeers = () => { + function updatePeers(): void { setStreams(window.sync.streams); - }; + } useEffect(() => { const { sync } = window; // sync object event listeners sync.on('ready', updatePeers); sync.on('peers', updatePeers); - sync.on('stream', ({ peerId, stream }) => { - addStream({ peerId, stream }); - setFocusStream(stream); - setFocusId(peerId); - }); + sync.on( + 'stream', + ({ + peerId, + stream, + }: { + peerId: string; + stream: MediaStream; + }) => { + addStream({ peerId, stream }); + setFocusStream(stream); + setFocusId(peerId); + } + ); sync.on('peerId', setMyPeerId); // get user media getMediaStream(); @@ -125,15 +142,16 @@ const VideoChat = () => { ? false : focusStream !== localStream } + width="" stream={focusStream || localStream} - name={getName(focusId)} + name={focusId ? getName(focusId) : 'player'} /> - {Object.keys(streams).map(id => { + {Object.keys(streams).map((id: string) => { if ( focusStream === streams[id] || (!focusStream && streams[id] === localStream) @@ -159,6 +177,6 @@ const VideoChat = () => { ); -}; +} export default VideoChat; diff --git a/src/index.js b/src/index.tsx similarity index 100% rename from src/index.js rename to src/index.tsx diff --git a/src/lib/emitter.js b/src/lib/emitter.ts similarity index 56% rename from src/lib/emitter.js rename to src/lib/emitter.ts index 2bf3e69..852bf38 100644 --- a/src/lib/emitter.js +++ b/src/lib/emitter.ts @@ -1,10 +1,22 @@ +type Callback = (data: any) => void; + +interface IEmitter { + eventSubscibersMap: { + [event: string]: Callback[]; + }; + emit(event: string, data: any): void; + on(event: string, cb: Callback): void; +} + class Emitter { - eventSubscibersMap = {}; + eventSubscibersMap: { + [event: string]: Callback[]; + } = {}; - emit(event, data) { + emit(event: string, data: any): void { try { const subscribers = this.eventSubscibersMap[event] || []; - subscribers.forEach(cb => { + subscribers.forEach((cb: Callback) => { try { cb(data); } catch (err) { @@ -16,7 +28,7 @@ class Emitter { } } - on(event, cb) { + on(event: string, cb: Callback): void { if (!(event in this.eventSubscibersMap)) this.eventSubscibersMap[event] = []; if (this.eventSubscibersMap[event].indexOf(cb) === -1) diff --git a/src/lib/global/lib.d.ts b/src/lib/global/lib.d.ts new file mode 100644 index 0000000..dbcdddf --- /dev/null +++ b/src/lib/global/lib.d.ts @@ -0,0 +1,4 @@ +// they don't have any type defs :( +declare module 'y-webrtc' { + const WebrtcProvider: any; +} diff --git a/src/lib/global/profile.d.ts b/src/lib/global/profile.d.ts new file mode 100644 index 0000000..b36ed15 --- /dev/null +++ b/src/lib/global/profile.d.ts @@ -0,0 +1,5 @@ +type Profile = { + username: string; + color: string; + peerId?: string; +}; diff --git a/src/lib/global/window.d.ts b/src/lib/global/window.d.ts new file mode 100644 index 0000000..8e25bbc --- /dev/null +++ b/src/lib/global/window.d.ts @@ -0,0 +1,7 @@ +import SyncManager from 'sync-manager'; + +declare global { + interface Window { + sync: SyncManager; + } +} diff --git a/src/pages/room/room.jsx b/src/pages/room/room.jsx index 29e6a17..cab78e6 100644 --- a/src/pages/room/room.jsx +++ b/src/pages/room/room.jsx @@ -20,7 +20,7 @@ import Terminal from 'features/terminal/terminal'; import roomService from 'api/http/room-service'; import roomSocket from 'api/ws/room-socket'; import colors from 'constants/colors'; -import { setupSync } from '@/sync-manager'; +import { setupSync } from 'sync-manager'; import './room.css'; diff --git a/src/sync-manager.js b/src/sync-manager.ts similarity index 60% rename from src/sync-manager.js rename to src/sync-manager.ts index a51c2d4..c3e95b3 100644 --- a/src/sync-manager.js +++ b/src/sync-manager.ts @@ -3,12 +3,54 @@ import * as Y from 'yjs'; import Emitter from 'lib/emitter'; -class SyncManager extends Emitter { - streams = {}; +interface ISyncManager { + streams: { [peerId: string]: MediaStream }; + streamData: { + video: MediaStreamTrack; + audio: MediaStreamTrack; + }; + stream: MediaStream; + peerId: string; + profiles: { [peerId: string]: Profile }; + profile: Profile; + doc: Y.Doc; + webrtcProvider: typeof WebrtcProvider; + checkPeerId(): void; + getWebrtcConns(): any[]; + getPeers(): any[]; + getPeerById(peerId: string): any; + getPeerIds(): string[]; + getStream(peerId: string): MediaStream | null; + getUserMedia(): Promise; + getWebrtcConns(): any[]; + releaseUserMedia(): void; + setProfile(profile: Profile): void; + setStream(stream: MediaStream): void; + toggleLocalAudio(): void; + toggleLocalVideo(): void; +} + +class SyncManager extends Emitter implements ISyncManager { + streams: { [peerId: string]: MediaStream } = {}; + + streamData: { + video: MediaStreamTrack; + audio: MediaStreamTrack; + }; + + stream: MediaStream; + + peerId: string; - profiles = {}; + profiles: { [peerId: string]: Profile } = {}; - constructor(roomId) { + profile: Profile; + + doc: Y.Doc; + + webrtcProvider: typeof WebrtcProvider; + + constructor(roomId: string) { super(); this.doc = new Y.Doc(); const webrtcProvider = new WebrtcProvider( @@ -23,29 +65,32 @@ class SyncManager extends Emitter { ); this.webrtcProvider = webrtcProvider; - webrtcProvider.on('peers', info => { + webrtcProvider.on('peers', (info: any) => { console.log(info); const added = Array.from(info.added); const removed = Array.from(info.removed); - removed.forEach(peerId => { + removed.forEach((peerId: string) => { delete this.profiles[peerId]; this.emit('profiles', this.profiles); delete this.streams[peerId]; }); - added.forEach(peerId => { + added.forEach((peerId: string) => { const peerConn = this.getPeerById(peerId); if (peerConn) { // exchange user profile data - peerConn.peer.on('data', data => { - let dataJson = null; + peerConn.peer.on('data', (data: any) => { + let dataJson: any; try { dataJson = JSON.parse(data.toString()); } catch (err) { return; } - const { type, profileData } = dataJson; + const { + type, + profileData, + }: { type: string; profileData: Profile } = dataJson; if (type === 'profile-data') { this.profiles[peerId] = { ...profileData, @@ -68,7 +113,7 @@ class SyncManager extends Emitter { peerConn.peer.addStream(this.stream); } // receive peer streams - peerConn.peer.on('stream', stream => { + peerConn.peer.on('stream', (stream: MediaStream) => { console.log('got peer stream', peerId, stream); this.streams[peerId] = stream; this.emit('stream', { peerId, stream }); @@ -83,7 +128,7 @@ class SyncManager extends Emitter { }); this.checkPeerId(); - this.emit('peers'); + this.emit('peers', {}); }); webrtcProvider.on('synced', info => { @@ -93,7 +138,7 @@ class SyncManager extends Emitter { }); } - checkPeerId() { + checkPeerId(): void { if (!this.peerId) { this.peerId = this.webrtcProvider.room.peerId; if (this.peerId) { @@ -102,19 +147,19 @@ class SyncManager extends Emitter { } } - getWebrtcConns() { + getWebrtcConns(): any { return this.webrtcProvider?.room?.webrtcConns; } - getPeers() { + getPeers(): any[] { return Array.from(this.getWebrtcConns()?.values() || []); } - getPeerById(id) { + getPeerById(id: string): any { return this.getWebrtcConns()?.get(id) || null; } - getPeerIds() { + getPeerIds(): string[] { try { return Array.from(this.getWebrtcConns()?.keys() || []); } catch (err) { @@ -123,7 +168,7 @@ class SyncManager extends Emitter { return []; } - getStream(peerId) { + getStream(peerId: string): MediaStream | null { try { return this.streams[peerId]; } catch (err) { @@ -132,54 +177,56 @@ class SyncManager extends Emitter { return null; } - getUserMedia() { - return new Promise((resolve, reject) => { - const options = { - audio: true, - video: { - facingMode: 'user', + getUserMedia(): Promise { + return new Promise( + (resolve: (stream: MediaStream) => void, reject) => { + const options = { + audio: true, video: { + facingMode: 'user', + video: { + width: { ideal: 640 }, + height: { ideal: 360 }, + }, width: { ideal: 640 }, height: { ideal: 360 }, + frameRate: { + min: 1, + ideal: 15, + }, }, - width: { ideal: 640 }, - height: { ideal: 360 }, - frameRate: { - min: 1, - ideal: 15, - }, - }, - }; - try { - navigator.mediaDevices - .getUserMedia(options) - .then(resolve) - .catch(reject); - } catch (err) { - reject(err); + }; + try { + navigator.mediaDevices + .getUserMedia(options) + .then(resolve) + .catch(reject); + } catch (err) { + reject(err); + } } - }).then(stream => { + ).then(stream => { this.setStream(stream); return stream; }); } - releaseUserMedia() { + releaseUserMedia(): void { this.stream.getTracks().map(track => track.stop()); - this.stream = null; + this.stream = null!; } - toggleLocalAudio() { + toggleLocalAudio(): void { const { audio } = this.streamData; audio.enabled = !audio.enabled; } - toggleLocalVideo() { + toggleLocalVideo(): void { const { video } = this.streamData; video.enabled = !video.enabled; } - setStream(stream) { + setStream(stream: MediaStream): void { this.stream = stream; this.streamData = { audio: stream.getAudioTracks()[0], @@ -191,7 +238,7 @@ class SyncManager extends Emitter { }); } - setProfile(profile) { + setProfile(profile: Profile): void { this.profile = profile; this.on('peerId', peerId => { this.profiles[peerId] = profile; @@ -209,7 +256,7 @@ class SyncManager extends Emitter { } } -export function setupSync(roomId) { +export function setupSync(roomId: string): SyncManager { return new SyncManager(roomId); } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2b01542 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "outDir": "./dist/", // path to output directory + "sourceMap": true, // allow sourcemap support + "strictNullChecks": true, // enable strict null checks as a best practice + "module": "es6", // specify module code generation + "jsx": "react", // use typescript to transpile jsx to js + "target": "es5", // specify ECMAScript target version + "allowJs": true, // allow a partial TypeScript and JavaScript codebase + "allowSyntheticDefaultImports": true, + "moduleResolution": "node", + "baseUrl": "src", + }, + "include": [ + "src/", + "src/lib/global/" + ] +} \ No newline at end of file