From 18a67a6fe9408ce6abe91aaa5bad88db0decc6d4 Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Mon, 4 Nov 2024 09:10:58 -0800 Subject: [PATCH] chore: Scaffold browser telemetry --- .github/workflows/browser-telemetry.yml | 27 +++++++ package.json | 3 +- .../telemetry/browser-telemetry/README.md | 46 +++++++++++ .../browser-telemetry/__tests__/empty.test.ts | 4 + .../browser-telemetry/jest.config.json | 16 ++++ .../telemetry/browser-telemetry/package.json | 76 +++++++++++++++++++ .../telemetry/browser-telemetry/setup-jest.js | 24 ++++++ .../telemetry/browser-telemetry/src/index.ts | 0 .../browser-telemetry/tsconfig.eslint.json | 5 ++ .../telemetry/browser-telemetry/tsconfig.json | 34 +++++++++ .../browser-telemetry/tsconfig.ref.json | 7 ++ .../browser-telemetry/tsconfig.test.json | 27 +++++++ .../browser-telemetry/tsup.config.ts | 17 +++++ .../telemetry/browser-telemetry/typedoc.json | 5 ++ 14 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/browser-telemetry.yml create mode 100644 packages/telemetry/browser-telemetry/README.md create mode 100644 packages/telemetry/browser-telemetry/__tests__/empty.test.ts create mode 100644 packages/telemetry/browser-telemetry/jest.config.json create mode 100644 packages/telemetry/browser-telemetry/package.json create mode 100644 packages/telemetry/browser-telemetry/setup-jest.js create mode 100644 packages/telemetry/browser-telemetry/src/index.ts create mode 100644 packages/telemetry/browser-telemetry/tsconfig.eslint.json create mode 100644 packages/telemetry/browser-telemetry/tsconfig.json create mode 100644 packages/telemetry/browser-telemetry/tsconfig.ref.json create mode 100644 packages/telemetry/browser-telemetry/tsconfig.test.json create mode 100644 packages/telemetry/browser-telemetry/tsup.config.ts create mode 100644 packages/telemetry/browser-telemetry/typedoc.json diff --git a/.github/workflows/browser-telemetry.yml b/.github/workflows/browser-telemetry.yml new file mode 100644 index 0000000000..b14b4e0b7a --- /dev/null +++ b/.github/workflows/browser-telemetry.yml @@ -0,0 +1,27 @@ +name: telemetry/browser-telemetry + +on: + push: + branches: [main, 'feat/**'] + paths-ignore: + - '**.md' #Do not need to run CI for markdown changes. + pull_request: + branches: [main, 'feat/**'] + paths-ignore: + - '**.md' + +jobs: + build-test-browser-telemetry: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + registry-url: 'https://registry.npmjs.org' + - id: shared + name: Shared CI Steps + uses: ./actions/ci + with: + workspace_name: '@launchdarkly/browser-telemetry' + workspace_path: packages/telemetry/browser-telemetry diff --git a/package.json b/package.json index eb764fee94..7827582517 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "packages/tooling/jest/example/react-native-example", "packages/sdk/browser", "packages/sdk/browser/contract-tests/entity", - "packages/sdk/browser/contract-tests/adapter" + "packages/sdk/browser/contract-tests/adapter", + "packages/telemetry/browser-telemetry" ], "private": true, "scripts": { diff --git a/packages/telemetry/browser-telemetry/README.md b/packages/telemetry/browser-telemetry/README.md new file mode 100644 index 0000000000..ad5857ad2e --- /dev/null +++ b/packages/telemetry/browser-telemetry/README.md @@ -0,0 +1,46 @@ +# Telemetry integration for LaunchDarkly browser SDKs. + +# ⛔️⛔️⛔️⛔️ + +> [!WARNING] +> This is an alpha version. The API is not stabilized and will introduce breaking changes. + +TODO Add badges + +## LaunchDarkly overview + +[LaunchDarkly](https://www.launchdarkly.com) is a feature management platform that serves over 100 billion feature flags daily to help teams build better software, faster. [Get started](https://docs.launchdarkly.com/home/getting-started) using LaunchDarkly today! + +[![Twitter Follow](https://img.shields.io/twitter/follow/launchdarkly.svg?style=social&label=Follow&maxAge=2592000)](https://twitter.com/intent/follow?screen_name=launchdarkly) + +## Compatibility + +TODO + +## Setup + +TODO + +## Contributing + +We encourage pull requests and other contributions from the community. Check out our [contributing guidelines](CONTRIBUTING.md) for instructions on how to contribute to this SDK. + +## About LaunchDarkly + +- LaunchDarkly is a continuous delivery platform that provides feature flags as a service and allows developers to iterate quickly and safely. We allow you to easily flag your features and manage them from the LaunchDarkly dashboard. With LaunchDarkly, you can: + - Roll out a new feature to a subset of your users (like a group of users who opt-in to a beta tester group), gathering feedback and bug reports from real-world use cases. + - Gradually roll out a feature to an increasing percentage of users, and track the effect that the feature has on key metrics (for instance, how likely is a user to complete a purchase if they have feature A versus feature B?). + - Turn off a feature that you realize is causing performance problems in production, without needing to re-deploy, or even restart the application with a changed configuration file. + - Grant access to certain features based on user attributes, like payment plan (eg: users on the ‘gold’ plan get access to more features than users in the ‘silver’ plan). + - Disable parts of your application to facilitate maintenance, without taking everything offline. +- LaunchDarkly provides feature flag SDKs for a wide variety of languages and technologies. Check out [our documentation](https://docs.launchdarkly.com/sdk) for a complete list. +- Explore LaunchDarkly + - [launchdarkly.com](https://www.launchdarkly.com/ 'LaunchDarkly Main Website') for more information + - [docs.launchdarkly.com](https://docs.launchdarkly.com/ 'LaunchDarkly Documentation') for our documentation and SDK reference guides + - [apidocs.launchdarkly.com](https://apidocs.launchdarkly.com/ 'LaunchDarkly API Documentation') for our API documentation + - [blog.launchdarkly.com](https://blog.launchdarkly.com/ 'LaunchDarkly Blog Documentation') for the latest product updates + +[node-otel-ci-badge]: https://github.com/launchdarkly/js-core/actions/workflows/node-otel.yml/badge.svg +[node-otel-ci]: https://github.com/launchdarkly/js-core/actions/workflows/node-otel.yml +[node-otel-npm-badge]: https://img.shields.io/npm/v/@launchdarkly/node-server-sdk-otel.svg?style=flat-square +[node-otel-npm-link]: https://www.npmjs.com/package/@launchdarkly/node-server-sdk-otel diff --git a/packages/telemetry/browser-telemetry/__tests__/empty.test.ts b/packages/telemetry/browser-telemetry/__tests__/empty.test.ts new file mode 100644 index 0000000000..759ca77be0 --- /dev/null +++ b/packages/telemetry/browser-telemetry/__tests__/empty.test.ts @@ -0,0 +1,4 @@ +it('runs tests', () => { + // Placeholder so CI can run tests. + expect(true).toBeTruthy(); +}); diff --git a/packages/telemetry/browser-telemetry/jest.config.json b/packages/telemetry/browser-telemetry/jest.config.json new file mode 100644 index 0000000000..6d2e223cd6 --- /dev/null +++ b/packages/telemetry/browser-telemetry/jest.config.json @@ -0,0 +1,16 @@ +{ + "verbose": true, + "testEnvironment": "jest-environment-jsdom", + "testPathIgnorePatterns": ["./dist", "./src"], + "testMatch": ["**.test.ts"], + "setupFiles": ["./setup-jest.js"], + "transform": { + "^.+\\.ts$": [ + "ts-jest", + { + "tsConfig": "tsconfig.test.json" + } + ], + "^.+.tsx?$": ["ts-jest", {}] + } +} diff --git a/packages/telemetry/browser-telemetry/package.json b/packages/telemetry/browser-telemetry/package.json new file mode 100644 index 0000000000..a54159265b --- /dev/null +++ b/packages/telemetry/browser-telemetry/package.json @@ -0,0 +1,76 @@ +{ + "name": "@launchdarkly/browser-telemetry", + "version": "0.0.9", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "require": { + "types": "./dist/index.d.cts", + "require": "./dist/index.cjs" + }, + "import": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + } + }, + "files": [ + "dist" + ], + "description": "Telemetry integration for LaunchDarkly browser SDKs.", + "scripts": { + "test": "npx jest --runInBand", + "build": "tsup", + "prettier": "prettier --write 'src/*.@(js|ts|tsx|json)'", + "check": "yarn && yarn prettier && yarn lint && tsc && yarn test", + "lint": "npx eslint . --ext .ts" + }, + "homepage": "https://github.com/launchdarkly/js-core/tree/main/packages/telemetry/browser-telemetry", + "repository": { + "type": "git", + "url": "git+https://github.com/launchdarkly/js-core.git" + }, + "keywords": [ + "launchdarkly", + "analytics", + "telemetry" + ], + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/launchdarkly/js-core/issues" + }, + "dependencies": { + "rrweb": "2.0.0-alpha.4", + "tracekit": "^0.4.6" + }, + "peerDependencies": { + "launchdarkly-js-client-sdk": "^3.4.0" + }, + "devDependencies": { + "@jest/globals": "^29.7.0", + "@trivago/prettier-plugin-sort-imports": "^4.1.1", + "@types/jest": "^29.5.11", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", + "eslint": "^8.45.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.1.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", + "eslint-plugin-prettier": "^5.0.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "launchdarkly-js-client-sdk": "^3.4.0", + "launchdarkly-js-test-helpers": "^2.2.0", + "prettier": "^3.0.0", + "rimraf": "^5.0.5", + "ts-jest": "^29.1.1", + "tsup": "^8.3.5", + "typedoc": "0.25.0", + "typescript": "^5.5.3" + } +} diff --git a/packages/telemetry/browser-telemetry/setup-jest.js b/packages/telemetry/browser-telemetry/setup-jest.js new file mode 100644 index 0000000000..e17ac62cb1 --- /dev/null +++ b/packages/telemetry/browser-telemetry/setup-jest.js @@ -0,0 +1,24 @@ +const { TextEncoder, TextDecoder } = require('node:util'); +const crypto = require('node:crypto'); + +global.TextEncoder = TextEncoder; + +Object.assign(window, { TextDecoder, TextEncoder }); + +// Based on: +// https://stackoverflow.com/a/71750830 + +Object.defineProperty(global.self, 'crypto', { + value: { + getRandomValues: (arr) => crypto.randomBytes(arr.length), + subtle: { + digest: (algorithm, data) => { + return new Promise((resolve) => + resolve( + crypto.createHash(algorithm.toLowerCase().replace('-', '')).update(data).digest(), + ), + ); + }, + }, + }, +}); diff --git a/packages/telemetry/browser-telemetry/src/index.ts b/packages/telemetry/browser-telemetry/src/index.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/telemetry/browser-telemetry/tsconfig.eslint.json b/packages/telemetry/browser-telemetry/tsconfig.eslint.json new file mode 100644 index 0000000000..8241f86c36 --- /dev/null +++ b/packages/telemetry/browser-telemetry/tsconfig.eslint.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["/**/*.ts", "/**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/packages/telemetry/browser-telemetry/tsconfig.json b/packages/telemetry/browser-telemetry/tsconfig.json new file mode 100644 index 0000000000..7306c5b0c6 --- /dev/null +++ b/packages/telemetry/browser-telemetry/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationMap": true, + "lib": ["ES2017", "dom"], + "module": "ESNext", + "moduleResolution": "node", + "noImplicitOverride": true, + "resolveJsonModule": true, + "rootDir": ".", + "outDir": "dist", + "skipLibCheck": true, + "sourceMap": false, + "strict": true, + "stripInternal": true, + "target": "ES2017", + "types": ["node", "jest"], + "allowJs": true + }, + "include": ["src"], + "exclude": [ + "vite.config.ts", + "__tests__", + "dist", + "docs", + "example", + "node_modules", + "babel.config.js", + "setup-jest.js", + "rollup.config.js", + "**/*.test.ts*" + ] +} diff --git a/packages/telemetry/browser-telemetry/tsconfig.ref.json b/packages/telemetry/browser-telemetry/tsconfig.ref.json new file mode 100644 index 0000000000..3925f645be --- /dev/null +++ b/packages/telemetry/browser-telemetry/tsconfig.ref.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*", "package.json", "__tests__/index.test.ts"], + "compilerOptions": { + "composite": true + } +} diff --git a/packages/telemetry/browser-telemetry/tsconfig.test.json b/packages/telemetry/browser-telemetry/tsconfig.test.json new file mode 100644 index 0000000000..6087e302dd --- /dev/null +++ b/packages/telemetry/browser-telemetry/tsconfig.test.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "lib": ["es6", "DOM"], + "module": "CommonJS", + "strict": true, + "noImplicitOverride": true, + "sourceMap": true, + "declaration": true, + "declarationMap": true, + "stripInternal": true + }, + "exclude": [ + "vite.config.ts", + "__tests__", + "dist", + "docs", + "example", + "node_modules", + "contract-tests", + "babel.config.js", + "jest.config.js", + "jestSetupFile.ts", + "**/*.test.ts*" + ] +} diff --git a/packages/telemetry/browser-telemetry/tsup.config.ts b/packages/telemetry/browser-telemetry/tsup.config.ts new file mode 100644 index 0000000000..4e632618c2 --- /dev/null +++ b/packages/telemetry/browser-telemetry/tsup.config.ts @@ -0,0 +1,17 @@ +// It is a dev dependency and the linter doesn't understand. +// eslint-disable-next-line import/no-extraneous-dependencies +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: { + index: 'src/index.ts', + }, + minify: true, + format: ['esm', 'cjs'], + splitting: false, + sourcemap: false, + clean: true, + external: ['launchdarkly-js-client-sdk'], + dts: true, + metafile: false, +}); diff --git a/packages/telemetry/browser-telemetry/typedoc.json b/packages/telemetry/browser-telemetry/typedoc.json new file mode 100644 index 0000000000..7ac616b544 --- /dev/null +++ b/packages/telemetry/browser-telemetry/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": ["../../../typedoc.base.json"], + "entryPoints": ["src/index.ts"], + "out": "docs" +}