From 928ff791fff4c7e83a914c2c00311e1114ed34b3 Mon Sep 17 00:00:00 2001 From: Marcos Passos Date: Mon, 18 May 2020 11:19:47 -0300 Subject: [PATCH] Restructure PlugJS --- .eslintrc.json | 1 + .../workflows/deploy-published-releases.yaml | 64 ++- LICENSE | 21 + README.md | 19 +- package-lock.json | 448 +++++++----------- package.json | 31 +- rollup.config.js | 33 +- rollup.min-config.js | 36 -- src/globalPlug.ts | 226 --------- src/index.ts | 55 +-- src/plug.ts | 236 ++++++++- src/plugin.ts | 18 +- src/sdk/evaluation.ts | 2 + src/sdk/event.ts | 1 + src/sdk/index.ts | 4 + src/sdk/json.ts | 1 + src/sdk/tracking.ts | 2 + src/sdk/validation.ts | 10 + src/singleton.ts | 3 - test/index.test.ts | 6 +- tsconfig.json | 6 +- 21 files changed, 517 insertions(+), 706 deletions(-) create mode 100644 LICENSE delete mode 100644 rollup.min-config.js delete mode 100644 src/globalPlug.ts create mode 100644 src/sdk/evaluation.ts create mode 100644 src/sdk/event.ts create mode 100644 src/sdk/index.ts create mode 100644 src/sdk/json.ts create mode 100644 src/sdk/tracking.ts create mode 100644 src/sdk/validation.ts delete mode 100644 src/singleton.ts diff --git a/.eslintrc.json b/.eslintrc.json index afce925aa..31c235130 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -49,6 +49,7 @@ "consistent-return": "off", "default-case": "off", "import/extensions": ["error", "never"], + "import/no-unresolved": "off", "import/prefer-default-export": "off", "indent": ["error", 4, {"SwitchCase": 1}], "linebreak-style": ["error", "unix"], diff --git a/.github/workflows/deploy-published-releases.yaml b/.github/workflows/deploy-published-releases.yaml index 4ab63a62e..89bcdac8a 100644 --- a/.github/workflows/deploy-published-releases.yaml +++ b/.github/workflows/deploy-published-releases.yaml @@ -27,32 +27,38 @@ jobs: npm ci rm -rf ~/.npmrc - - name: Build bundles + - name: Build package run: |- - npm run rollup - npm run rollup-min + npm run build - # Clear dependencies from package-lock.json - mv package.json package-full.json - cat package-full.json | \ - jq 'del(.dependencies) | del(.devDependencies) | del(.testDependencies) | del(.jest) | del(.scripts)' | \ - jq '.main = "build/index.js" | .types = "build/index.d.ts"' | \ - jq ".version = \"${GITHUB_REF##*/}\"" > package.json - cat package.json + - name: Prepare release + run: |- + cp package.json LICENSE README.md build/ + cd build + sed -i -e "s~\"version\": \"0.0.0-dev\"~\"version\": \"${GITHUB_REF##*/}\"~" package.json - echo - echo "Clearing lock" - echo + - name: Publish pre-release to NPM + if: ${{ github.event.release.prerelease }} + run: |- + cd build + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc + npm publish --access public --tag next + env: + NPM_TOKEN: ${{ secrets.BOT_TOKEN }} - rm -rf node_modules - npm install - rm package-full.json + - name: Publish release to NPM + if: ${{ !github.event.release.prerelease }} + run: |- + cd build + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc + npm publish --access public + env: + NPM_TOKEN: ${{ secrets.BOT_TOKEN }} - - name: Upload artifacts - uses: actions/upload-artifact@v1 - with: - name: bundle - path: build + - name: Bundle package + run: |- + rm -rf build + npm run bundle - name: Authenticate to GCP if: ${{ !github.event.release.prerelease }} @@ -70,19 +76,3 @@ jobs: # Allow for faster updates during beta, should be removed once its stable enough to distribute over global cdn gsutil -m setmeta -h "Cache-Control: no-cache, no-store, no-transform" "gs://${GCLOUD_BUCKET}/js/v1/lib/plug.js" - - - name: npm publish prerelease - if: ${{ github.event.release.prerelease }} - run: |- - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc - npm publish --access public --tag next - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: npm publish - if: ${{ !github.event.release.prerelease }} - run: |- - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc - npm publish --access public - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..c0b6d834e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Croct.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 9145d1caa..14f9cfa78 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- Croct + Croct
Plug JS @@ -9,17 +9,17 @@

Version + Build + Maintainability + Coverage Gzipped Size - Build - Maintainability - Coverage

- Releases + 📦Releases · - Report Bug + 🐞Report Bug · - Request Feature + ✨Request Feature

## Introduction @@ -90,7 +90,6 @@ Then, to run all tests: npm test ``` -## Copyright Notice -Copyright © 2015-2020 Croct Limited, All Rights Reserved. +## License -All information contained herein is, and remains the property of Croct Limited. The intellectual, design and technical concepts contained herein are proprietary to Croct Limited s and may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is strictly forbidden unless prior written permission is obtained from Croct Limited. +This project is released under the [MIT License](LICENSE). diff --git a/package-lock.json b/package-lock.json index b9d530006..972b99027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -357,10 +357,10 @@ "minimist": "^1.2.0" } }, - "@croct-tech/sdk": { - "version": "0.1.4", - "resolved": "https://npm.pkg.github.com/download/@croct-tech/sdk/0.1.4/b8423523d177b6d05f21af4bd2531f0c7e10134a0a01d32166710749a5fdf6e7", - "integrity": "sha512-hNo469GWbYE+iiPS8IGs7+1sudeehmkkY1aCQSfUvxTbZmhnC81Xi4OG9jE+hVqzu4OH3aGH7TYk1ah2OI7LUg==" + "@croct/sdk": { + "version": "0.2.0-alpha.4", + "resolved": "https://registry.npmjs.org/@croct/sdk/-/sdk-0.2.0-alpha.4.tgz", + "integrity": "sha512-g7nUYQ/+EiVeSNJL8Y1A0obajWYe2tdDlFI/daqMdFUuQbD+wca5QMEDKEZYMeZT95gtOXvFqU1iIh485InNMw==" }, "@istanbuljs/load-nyc-config": { "version": "1.0.0", @@ -1363,6 +1363,63 @@ "@types/yargs": "^13.0.0" } }, + "@rollup/plugin-commonjs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-11.1.0.tgz", + "integrity": "sha512-Ycr12N3ZPN96Fw2STurD21jMqzKwL9QuFhms3SD7KKRK7oaXUsBU9Zt0jL/rOPHiPYisI21/rXGO3jr9BnLHUA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8", + "commondir": "^1.0.1", + "estree-walker": "^1.0.1", + "glob": "^7.1.2", + "is-reference": "^1.1.2", + "magic-string": "^0.25.2", + "resolve": "^1.11.0" + } + }, + "@rollup/plugin-node-resolve": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", + "integrity": "sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8", + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.14.2" + } + }, + "@rollup/plugin-typescript": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-4.1.1.tgz", + "integrity": "sha512-KYZCn1Iw9hZWkeEPqPs5YjlmvSjR7UdezVca8z0e8rm/29wU24UD9Y4IZHhnc9tm749hzsgBTiOUxA85gfShEQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.1", + "resolve": "^1.14.1" + } + }, + "@rollup/pluginutils": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.10.tgz", + "integrity": "sha512-d44M7t+PjmMrASHbhgpSbVgtL6EFyX7J4mYxwQ/c5eoaE6N2VgCgEcWVzNnwycIloti+/MpwFr8qfw+nRw00sw==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + } + } + }, "@sinonjs/commons": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", @@ -1426,9 +1483,9 @@ "dev": true }, "@types/estree": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.42.tgz", - "integrity": "sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ==", + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, "@types/graceful-fs": { @@ -2275,42 +2332,6 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -2363,6 +2384,12 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -2591,16 +2618,6 @@ "webidl-conversions": "^4.0.2" } }, - "dts-bundle-generator": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/dts-bundle-generator/-/dts-bundle-generator-3.3.1.tgz", - "integrity": "sha512-ePli14sf9223BwvaeuKpZYrlgAVJFf/OtZXLKtvs3khASEV62yXXN5QHpP2vRNCW7gNgxgTNPuM5G2d/N94oyw==", - "dev": true, - "requires": { - "typescript": ">=2.6.1", - "yargs": "~13.3.0" - } - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -2925,9 +2942,9 @@ "dev": true }, "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, "esutils": { @@ -3283,6 +3300,77 @@ } } }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "dependencies": { + "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" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "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" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "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 + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -3342,12 +3430,12 @@ } }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } @@ -3949,14 +4037,6 @@ "dev": true, "requires": { "@types/estree": "0.0.39" - }, - "dependencies": { - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - } } }, "is-regex": { @@ -7854,86 +7934,31 @@ } }, "rollup": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", - "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" - } - }, - "rollup-plugin-commonjs": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" - } - }, - "rollup-plugin-dts": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-1.4.0.tgz", - "integrity": "sha512-Yvag9u/uXgX+49qascRe4aFSrSMrY3rUAnbXrl6Y/08GL2cylosfCd5a1siOhHM6u1n4wyR9Nnc04cjceeedfw==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.10.2.tgz", + "integrity": "sha512-tivFM8UXBlYOUqpBYD3pRktYpZvK/eiCQ190eYlrAyrpE/lzkyG2gbawroNdbwmzyUc7Y4eT297xfzv0BDh9qw==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3" - } - }, - "rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "dev": true, - "requires": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" + "fsevents": "~2.1.2" } }, "rollup-plugin-typescript2": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.21.2.tgz", - "integrity": "sha512-TfX+HLJ99p/P8kYZJdNYp9iGVWFCrj+G/V56LbEYtBqVMVHbGkrSoDH8AJjDtyRp6J9VosaKKmnBDBxhDo7TZw==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.27.1.tgz", + "integrity": "sha512-RJl77Bbj1EunAQDC3dK/O2HWuSUX3oJbRGzyLoS5o9W4Hs1Nix3Gavqj1Lzs5Y6Ff4H2xXfmZ1WWUQCYocSbzQ==", "dev": true, "requires": { - "fs-extra": "7.0.1", - "resolve": "1.10.1", - "rollup-pluginutils": "2.6.0", - "tslib": "1.9.3" + "@rollup/pluginutils": "^3.0.8", + "find-cache-dir": "^3.3.1", + "fs-extra": "8.1.0", + "resolve": "1.15.1", + "tslib": "1.11.2" }, "dependencies": { - "resolve": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", - "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "rollup-pluginutils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.6.0.tgz", - "integrity": "sha512-aGQwspEF8oPKvg37u3p7h0cYNwmJR1sCBMZGZ5b9qy8HGtETknqjzcxrDRrcAnJNXN18lBH4Q9vZYth/p4n8jQ==", - "dev": true, - "requires": { - "estree-walker": "^0.6.0", - "micromatch": "^3.1.10" - } - }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.2.tgz", + "integrity": "sha512-tTSkux6IGPnUGUd1XAZHcpu85MOkIl5zX49pO+jfsie3eP0B6pyhOlLXm3cAC6T7s+euSDDUUV+Acop5WmtkVg==", "dev": true } } @@ -7950,15 +7975,6 @@ "uglify-js": "^3.4.9" } }, - "rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1" - } - }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -8856,9 +8872,9 @@ } }, "typescript": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", - "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz", + "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==", "dev": true }, "uglify-js": { @@ -9084,42 +9100,6 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -9170,102 +9150,6 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } } diff --git a/package.json b/package.json index 5b3e1b17f..500a20998 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,12 @@ "name": "@croct/plug", "version": "0.0.0-dev", "description": "The hassle-free way to integrate Croct into any web application.", + "license": "MIT", "author": { "name": "Croct", "email": "plug-js+lib@croct.com", "url": "https://croct.com" }, - "license": "UNLICENSED", "keywords": [ "croct", "personalization", @@ -15,8 +15,8 @@ "javascript", "typescript" ], - "main": "build/index.js", - "types": "build/index.d.ts", + "main": "index.js", + "types": "index.d.ts", "repository": { "type": "git", "url": "git+https://github.com/croct-tech/plug-js.git" @@ -26,40 +26,39 @@ }, "homepage": "https://github.com/croct-tech/plug-js", "scripts": { - "validate": "tsc --noEmit", "lint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "test": "jest -c jest.config.js --coverage", - "rollup": "rollup -c rollup.config.js", - "rollup-min": "rollup -c rollup.min-config.js" + "validate": "tsc --noEmit", + "build": "tsc", + "bundle": "rollup -c rollup.config.js" }, "dependencies": { - "@croct-tech/sdk": "0.1.4" + "@croct/sdk": "^0.2.0-alpha.4" }, "devDependencies": { + "@rollup/plugin-commonjs": "^11.1.0", + "@rollup/plugin-node-resolve": "^7.1.3", + "@rollup/plugin-typescript": "^4.1.1", "@types/jest": "^24.0.15", "@typescript-eslint/eslint-plugin": "^2.30.0", "@typescript-eslint/parser": "^2.30.0", - "dts-bundle-generator": "^3.3.1", "eslint": "^6.8.0", "eslint-config-airbnb-base": "^14.1.0", "eslint-plugin-import": "^2.20.2", "eslint-plugin-jest": "^23.7.0", "jest": "^25.5.4", - "rollup": "^1.31.0", - "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-dts": "^1.4.0", - "rollup-plugin-node-resolve": "^5.2.0", - "rollup-plugin-typescript2": "^0.21.2", + "rollup": "^2.10.2", + "rollup-plugin-typescript2": "^0.27.1", "rollup-plugin-uglify": "^6.0.4", "temp-dir": "^2.0.0", "ts-jest": "^25.4.0", - "typescript": "^3.7.5" + "typescript": "^3.9.2" }, "browserslist": [ "last 1 version" ], "files": [ - "build/index.js", - "build/index.d.ts" + "**/*.js", + "**/*.ts" ] } diff --git a/rollup.config.js b/rollup.config.js index 5f5b22587..c9da37032 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,32 +1,39 @@ -import resolve from 'rollup-plugin-node-resolve'; +import resolve from '@rollup/plugin-node-resolve'; import typescript from 'rollup-plugin-typescript2'; import tempDir from 'temp-dir'; -import dts from 'rollup-plugin-dts'; -import commonjs from 'rollup-plugin-commonjs'; +import {uglify} from 'rollup-plugin-uglify'; +import commonjs from '@rollup/plugin-commonjs'; export default () => { return [ { input: 'src/index.ts', output: { - file: 'build/index.js', - format: 'commonjs', - exports: 'named', - sourcemap: true, + file: 'build/plug.min.js', + name: 'croct', + format: 'iife', + }, + treeshake: { + propertyReadSideEffects: false, }, plugins: [ resolve(), commonjs(), typescript({ cacheRoot: `${tempDir}/.rpt2_cache`, - useTsconfigDeclarationDir: true, + tsconfigOverride: { + compilerOptions: { + module: "ES2015" + } + }, + }), + uglify({ + compress: { + unused: true, + dead_code: true, + }, }), ], }, - { - input: './build/declarations/index.d.ts', - output: [{file: 'build/index.d.ts', format: 'commonjs'}], - plugins: [dts({respectExternal: true})], - }, ]; }; diff --git a/rollup.min-config.js b/rollup.min-config.js deleted file mode 100644 index ab67ee97a..000000000 --- a/rollup.min-config.js +++ /dev/null @@ -1,36 +0,0 @@ -import resolve from 'rollup-plugin-node-resolve'; -import typescript from 'rollup-plugin-typescript2'; -import tempDir from 'temp-dir'; -import {uglify} from 'rollup-plugin-uglify'; -import commonjs from 'rollup-plugin-commonjs'; - -export default () => { - return [ - { - input: 'src/singleton.ts', - output: { - file: 'build/plug.min.js', - name: 'croct', - format: 'iife', - sourcemap: false, - }, - treeshake: { - propertyReadSideEffects: false, - }, - plugins: [ - resolve(), - commonjs(), - typescript({ - cacheRoot: `${tempDir}/.rpt2_cache`, - useTsconfigDeclarationDir: true, - }), - uglify({ - compress: { - unused: true, - dead_code: true, - }, - }), - ], - }, - ]; -}; diff --git a/src/globalPlug.ts b/src/globalPlug.ts deleted file mode 100644 index 39a1285b4..000000000 --- a/src/globalPlug.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { - EvaluationFacadeOptions as EvaluationOptions, - ExternalEvent, - ExternalEventPayload, - ExternalEventType, - JsonValue, - Logger, - SdkFacade, - SessionFacade, - TrackerFacade, - UserFacade, -} from '@croct-tech/sdk'; -import {Plug, Configuration} from './plug'; -import {Plugin, PluginFactory} from './plugin'; - -const PLUGIN_NAMESPACE = 'Plugin'; - -export default class GlobalPlug implements Plug { - private pluginFactories: {[key: string]: PluginFactory} = {}; - - private instance?: SdkFacade; - - private plugins: {[key: string]: Plugin} = {}; - - private initialize: {(): void}; - - private initialized: Promise; - - public constructor() { - this.initialized = new Promise(resolve => { - this.initialize = resolve; - }); - } - - public extend(name: string, plugin: PluginFactory): void { - if (this.pluginFactories[name] !== undefined) { - throw new Error(`Another plugin is already registered with name "${name}".`); - } - - this.pluginFactories[name] = plugin; - } - - public plug(configuration: Configuration): void { - if (this.instance !== undefined) { - const logger = this.instance.getLogger(); - - logger.info('Croct is already plugged in.'); - - return; - } - - const {plugins, ...sdkConfiguration} = configuration; - const sdk = SdkFacade.init(sdkConfiguration); - - this.instance = sdk; - - const logger = this.instance.getLogger(); - const pending: Promise[] = []; - - for (const [name, options] of Object.entries(plugins ?? {})) { - logger.debug(`Initializing plugin "${name}"...`); - - const factory = this.pluginFactories[name]; - - if (factory === undefined) { - logger.error(`Plugin "${name}" is not registered.`); - - continue; - } - - const plugin = factory({ - options: options, - sdk: { - tracker: sdk.tracker, - evaluator: sdk.evaluator, - user: sdk.user, - session: sdk.session, - tab: sdk.context.getTab(), - getLogger: (...namespace: string[]): Logger => { - return sdk.getLogger(PLUGIN_NAMESPACE, name, ...namespace); - }, - getTabStorage: (...namespace: string[]): Storage => { - return sdk.getTabStorage(PLUGIN_NAMESPACE, name, ...namespace); - }, - getBrowserStorage: (...namespace: string[]): Storage => { - return sdk.getBrowserStorage(PLUGIN_NAMESPACE, name, ...namespace); - }, - }, - }); - - logger.debug(`Plugin "${name}" initialized`); - - if (typeof plugin !== 'object') { - continue; - } - - this.plugins[name] = plugin; - - const promise = plugin.enable(); - - if (!(promise instanceof Promise)) { - logger.debug(`Plugin "${name}" enabled`); - - continue; - } - - pending.push( - promise - .then(() => logger.debug(`Plugin "${name}" enabled`)) - .catch(() => logger.error(`Failed to enable plugin "${name}"`)), - ); - } - - Promise.all(pending).then(() => { - this.initialize(); - - logger.debug('Initialization complete'); - }); - } - - public get plugged(): Promise { - return this.initialized.then(() => this); - } - - public get flushed(): Promise { - return this.tracker.flushed.then(() => this); - } - - public get sdk(): SdkFacade { - if (this.instance === undefined) { - throw new Error('Croct is not plugged in.'); - } - - return this.instance; - } - - public get tracker(): TrackerFacade { - return this.sdk.tracker; - } - - public get user(): UserFacade { - return this.sdk.user; - } - - public get session(): SessionFacade { - return this.sdk.session; - } - - public isAnonymous(): boolean { - return this.sdk.context.isAnonymous(); - } - - public getUserId(): string | null { - return this.sdk.context.getUser(); - } - - public identify(userId: string): void { - this.sdk.identify(userId); - } - - public anonymize(): void { - this.sdk.anonymize(); - } - - public setToken(token: string): void { - this.sdk.setToken(token); - } - - public unsetToken(): void { - this.sdk.unsetToken(); - } - - public track(type: T, payload: ExternalEventPayload): Promise> { - return this.sdk.track(type, payload); - } - - public evaluate(expression: string, options: EvaluationOptions = {}): Promise { - return this.sdk.evaluate(expression, options); - } - - public async unplug(): Promise { - if (this.instance === undefined) { - return; - } - - const logger = this.sdk.getLogger(); - const pending: Promise[] = []; - - for (const [pluginName, controller] of Object.entries(this.plugins)) { - if (typeof controller.disable !== 'function') { - continue; - } - - logger.debug(`Disabling plugin "${pluginName}"...`); - - const promise = controller.disable(); - - if (!(promise instanceof Promise)) { - logger.debug(`Plugin "${pluginName}" disabled`); - - continue; - } - - pending.push( - promise - .then(() => logger.debug(`Plugin "${pluginName}" disabled`)) - .catch(() => logger.error(`Failed to disable "${pluginName}"`)), - ); - } - - await Promise.all(pending); - - try { - await this.instance.close(); - } finally { - delete this.instance; - - this.plugins = {}; - this.initialized = new Promise(resolve => { - this.initialize = resolve; - }); - - logger.info('🔌 Croct has been unplugged.'); - } - } -} diff --git a/src/index.ts b/src/index.ts index 418967804..e3d9a57a5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,53 +1,4 @@ -import { - SdkFacade as Sdk, - Logger, - Tab, - UserFacade, - SessionFacade, - TrackerFacade as Tracker, - EvaluatorFacade as Evaluator, - EvaluationFacadeOptions as EvaluationOptions, - EvaluationErrorType, - EvaluationError, - ExpressionError, - Event, - EventType, - ExternalEvent, - ExternalEventPayload, - ExternalEventType, - EventListener, - EventInfo, - JsonValue, -} from '@croct-tech/sdk'; -import {Plug, Configuration} from './plug'; -import {Plugin, PluginArguments, PluginFactory, PluginSdk} from './plugin'; +import {Configuration, Plug, GlobalPlug} from './plug'; -export { - Sdk, - Tab, - UserFacade, - SessionFacade, - Tracker, - Logger, - Evaluator, - EvaluationOptions, - Event, - EventType, - ExternalEventType, - ExternalEventPayload, - EventListener, - EventInfo, - ExternalEvent, - EvaluationErrorType, - EvaluationError, - ExpressionError, - JsonValue, - Plug, - Configuration, - PluginFactory, - PluginArguments, - Plugin, - PluginSdk, -}; - -export {default} from './singleton'; +export {Configuration, Plug}; +export default new GlobalPlug(); diff --git a/src/plug.ts b/src/plug.ts index d042f1cf3..0d37968aa 100644 --- a/src/plug.ts +++ b/src/plug.ts @@ -1,15 +1,12 @@ -import { - EvaluationFacadeOptions as EvaluationOptions, - ExternalEvent, - ExternalEventPayload, - ExternalEventType, - JsonValue, - SdkFacade, - SdkFacadeConfiguration, - SessionFacade, - TrackerFacade, - UserFacade, -} from '@croct-tech/sdk'; +import {ExternalEvent, ExternalEventPayload, ExternalEventType} from '@croct/sdk/event'; +import {Logger} from '@croct/sdk/logging'; +import {JsonValue} from '@croct/sdk/json'; +import SessionFacade from '@croct/sdk/facade/sessionFacade'; +import UserFacade from '@croct/sdk/facade/userFacade'; +import Tracker from '@croct/sdk/facade/trackerFacade'; +import {EvaluationOptions} from '@croct/sdk/facade/evaluatorFacade'; +import Sdk, {Configuration as SdkFacadeConfiguration} from '@croct/sdk/facade/sdkFacade'; +import {Plugin, PluginFactory} from './plugin'; interface PluginConfigurations { [key: string]: any; @@ -20,10 +17,9 @@ export type Configuration = SdkFacadeConfiguration & { } export interface Plug { - readonly tracker: TrackerFacade; + readonly tracker: Tracker; readonly user: UserFacade; readonly session: SessionFacade; - readonly sdk: SdkFacade; readonly flushed: Promise; readonly plugged: Promise; @@ -47,3 +43,215 @@ export interface Plug { unplug(): Promise; } + +const PLUGIN_NAMESPACE = 'Plugin'; + +export class GlobalPlug implements Plug { + private pluginFactories: {[key: string]: PluginFactory} = {}; + + private instance?: Sdk; + + private plugins: {[key: string]: Plugin} = {}; + + private initialize: {(): void}; + + private initialized: Promise; + + public constructor() { + this.initialized = new Promise(resolve => { + this.initialize = resolve; + }); + } + + public extend(name: string, plugin: PluginFactory): void { + if (this.pluginFactories[name] !== undefined) { + throw new Error(`Another plugin is already registered with name "${name}".`); + } + + this.pluginFactories[name] = plugin; + } + + public plug(configuration: Configuration): void { + if (this.instance !== undefined) { + const logger = this.instance.getLogger(); + + logger.info('Croct is already plugged in.'); + + return; + } + + const {plugins, ...sdkConfiguration} = configuration; + const sdk = Sdk.init(sdkConfiguration); + + this.instance = sdk; + + const logger = this.instance.getLogger(); + const pending: Promise[] = []; + + for (const [name, options] of Object.entries(plugins ?? {})) { + logger.debug(`Initializing plugin "${name}"...`); + + const factory = this.pluginFactories[name]; + + if (factory === undefined) { + logger.error(`Plugin "${name}" is not registered.`); + + continue; + } + + const plugin = factory({ + options: options, + sdk: { + tracker: sdk.tracker, + evaluator: sdk.evaluator, + user: sdk.user, + session: sdk.session, + tab: sdk.context.getTab(), + getLogger: (...namespace: string[]): Logger => { + return sdk.getLogger(PLUGIN_NAMESPACE, name, ...namespace); + }, + getTabStorage: (...namespace: string[]): Storage => { + return sdk.getTabStorage(PLUGIN_NAMESPACE, name, ...namespace); + }, + getBrowserStorage: (...namespace: string[]): Storage => { + return sdk.getBrowserStorage(PLUGIN_NAMESPACE, name, ...namespace); + }, + }, + }); + + logger.debug(`Plugin "${name}" initialized`); + + if (typeof plugin !== 'object') { + continue; + } + + this.plugins[name] = plugin; + + const promise = plugin.enable(); + + if (!(promise instanceof Promise)) { + logger.debug(`Plugin "${name}" enabled`); + + continue; + } + + pending.push( + promise + .then(() => logger.debug(`Plugin "${name}" enabled`)) + .catch(() => logger.error(`Failed to enable plugin "${name}"`)), + ); + } + + Promise.all(pending).then(() => { + this.initialize(); + + logger.debug('Initialization complete'); + }); + } + + public get plugged(): Promise { + return this.initialized.then(() => this); + } + + public get flushed(): Promise { + return this.tracker.flushed.then(() => this); + } + + public get sdk(): Sdk { + if (this.instance === undefined) { + throw new Error('Croct is not plugged in.'); + } + + return this.instance; + } + + public get tracker(): Tracker { + return this.sdk.tracker; + } + + public get user(): UserFacade { + return this.sdk.user; + } + + public get session(): SessionFacade { + return this.sdk.session; + } + + public isAnonymous(): boolean { + return this.sdk.context.isAnonymous(); + } + + public getUserId(): string | null { + return this.sdk.context.getUser(); + } + + public identify(userId: string): void { + this.sdk.identify(userId); + } + + public anonymize(): void { + this.sdk.anonymize(); + } + + public setToken(token: string): void { + this.sdk.setToken(token); + } + + public unsetToken(): void { + this.sdk.unsetToken(); + } + + public track(type: T, payload: ExternalEventPayload): Promise> { + return this.sdk.track(type, payload); + } + + public evaluate(expression: string, options: EvaluationOptions = {}): Promise { + return this.sdk.evaluate(expression, options); + } + + public async unplug(): Promise { + if (this.instance === undefined) { + return; + } + + const logger = this.sdk.getLogger(); + const pending: Promise[] = []; + + for (const [pluginName, controller] of Object.entries(this.plugins)) { + if (typeof controller.disable !== 'function') { + continue; + } + + logger.debug(`Disabling plugin "${pluginName}"...`); + + const promise = controller.disable(); + + if (!(promise instanceof Promise)) { + logger.debug(`Plugin "${pluginName}" disabled`); + + continue; + } + + pending.push( + promise + .then(() => logger.debug(`Plugin "${pluginName}" disabled`)) + .catch(() => logger.error(`Failed to disable "${pluginName}"`)), + ); + } + + await Promise.all(pending); + + try { + await this.instance.close(); + } finally { + delete this.instance; + + this.plugins = {}; + this.initialized = new Promise(resolve => { + this.initialize = resolve; + }); + + logger.info('🔌 Croct has been unplugged.'); + } + } +} diff --git a/src/plugin.ts b/src/plugin.ts index c29d6ddc6..72d03a893 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,15 +1,13 @@ -import { - TrackerFacade as Tracker, - EvaluatorFacade as Evaluator, - UserFacade, - SessionFacade, - Logger, - Tab, -} from '@croct-tech/sdk'; +import TrackerFacade from '@croct/sdk/facade/trackerFacade'; +import EvaluatorFacade from '@croct/sdk/facade/evaluatorFacade'; +import UserFacade from '@croct/sdk/facade/userFacade'; +import SessionFacade from '@croct/sdk/facade/sessionFacade'; +import Tab from '@croct/sdk/tab'; +import {Logger} from '@croct/sdk/logging'; export interface PluginSdk { - readonly tracker: Tracker; - readonly evaluator: Evaluator; + readonly tracker: TrackerFacade; + readonly evaluator: EvaluatorFacade; readonly user: UserFacade; readonly session: SessionFacade; readonly tab: Tab; diff --git a/src/sdk/evaluation.ts b/src/sdk/evaluation.ts new file mode 100644 index 000000000..f5a7dff60 --- /dev/null +++ b/src/sdk/evaluation.ts @@ -0,0 +1,2 @@ +export type {default as Evaluator, EvaluationOptions} from '@croct/sdk/facade/evaluatorFacade'; +export {EvaluationError, EvaluationErrorType, ExpressionError} from '@croct/sdk/evaluator'; diff --git a/src/sdk/event.ts b/src/sdk/event.ts new file mode 100644 index 000000000..76c31def0 --- /dev/null +++ b/src/sdk/event.ts @@ -0,0 +1 @@ +export type {Event, EventType, ExternalEvent, ExternalEventPayload, ExternalEventType} from '@croct/sdk/event'; diff --git a/src/sdk/index.ts b/src/sdk/index.ts new file mode 100644 index 000000000..665c67c88 --- /dev/null +++ b/src/sdk/index.ts @@ -0,0 +1,4 @@ +export type {Logger} from '@croct/sdk/logging'; +export type {default as SessionFacade} from '@croct/sdk/facade/sessionFacade'; +export type {default as UserFacade} from '@croct/sdk/facade/userFacade'; +export type {default as Tab} from '@croct/sdk/tab'; diff --git a/src/sdk/json.ts b/src/sdk/json.ts new file mode 100644 index 000000000..9d952106e --- /dev/null +++ b/src/sdk/json.ts @@ -0,0 +1 @@ +export * from '@croct/sdk/json'; diff --git a/src/sdk/tracking.ts b/src/sdk/tracking.ts new file mode 100644 index 000000000..d31b26bee --- /dev/null +++ b/src/sdk/tracking.ts @@ -0,0 +1,2 @@ +export type {default as Tracker} from '@croct/sdk/facade/trackerFacade'; +export type {EventInfo, EventListener} from '@croct/sdk/tracker'; diff --git a/src/sdk/validation.ts b/src/sdk/validation.ts new file mode 100644 index 000000000..a0f934669 --- /dev/null +++ b/src/sdk/validation.ts @@ -0,0 +1,10 @@ +export * from '@croct/sdk/validation'; +export * from '@croct/sdk/validation/jsonType'; +export {default as MixedSchema} from '@croct/sdk/validation/mixedSchema'; +export {default as BooleanType} from '@croct/sdk/validation/booleanType'; +export {default as ArrayType} from '@croct/sdk/validation/arrayType'; +export {default as NullType} from '@croct/sdk/validation/nullType'; +export {default as NumberType} from '@croct/sdk/validation/numberType'; +export {default as ObjectType} from '@croct/sdk/validation/objectType'; +export {default as StringType} from '@croct/sdk/validation/stringType'; +export {default as UnionType} from '@croct/sdk/validation/unionType'; diff --git a/src/singleton.ts b/src/singleton.ts deleted file mode 100644 index d59c39b5d..000000000 --- a/src/singleton.ts +++ /dev/null @@ -1,3 +0,0 @@ -import GlobalPlug from './globalPlug'; - -export default new GlobalPlug(); diff --git a/test/index.test.ts b/test/index.test.ts index 5ac5975e7..67633ccc1 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,7 +1,7 @@ -import {Logger, SdkFacade, SdkFacadeConfiguration} from '@croct-tech/sdk'; -import {Configuration} from '../src/plug'; +import SdkFacade, {Configuration as SdkFacadeConfiguration} from '@croct/sdk/facade/sdkFacade'; +import {Logger} from '../src/sdk'; import {Plugin, PluginFactory} from '../src/plugin'; -import GlobalPlug from '../src/globalPlug'; +import {GlobalPlug, Configuration} from '../src/plug'; describe('The Croct plug', () => { const appId = '7e9d59a9-e4b3-45d4-b1c7-48287f1e5e8a'; diff --git a/tsconfig.json b/tsconfig.json index 4205a8bd6..01a2e5c75 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "module": "es2015", + "module": "CommonJS", "target": "es5", "moduleResolution": "Node", "allowSyntheticDefaultImports": true, @@ -13,15 +13,13 @@ "noUnusedParameters": true, "strictNullChecks": true, "removeComments": false, - "sourceMap": true, "outDir": "build", "downlevelIteration": true, "declaration": true, - "declarationDir": "build/declarations", "lib": ["es6", "dom", "dom.iterable", "es2018.promise"] }, "include": [ "src/**/*.ts" ], "exclude": ["node_modules", "build"] -} \ No newline at end of file +}