From d04b0413e7ed9b7a09b74e5b77659c73ccba38ae Mon Sep 17 00:00:00 2001 From: Cal Courtney Date: Mon, 3 Jun 2024 17:07:07 +0100 Subject: [PATCH] chore: update markdown documentation --- .github/pull_request_template.md | 49 +++++ CONTRIBUTING.md | 74 +++---- LICENSE | 3 +- README.md | 338 ++++++------------------------- 4 files changed, 149 insertions(+), 315 deletions(-) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..795f3f1 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,49 @@ +# Pull Request Template + +## Description + +Please include a summary of the changes and the related issue. Explain the +motivation for the change and how it addresses the issue. Provide context if necessary. + +Fixes # (issue) + +## Type of Change + +Please delete options that are not relevant and add any that are. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to + not work as expected) +- [ ] Documentation update + +## Checklist + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published in downstream modules + +## How Has This Been Tested? + +Please describe the tests that you ran to verify your changes. Provide +instructions so we can reproduce. Include any relevant details for your test configuration. + +- [ ] Test A +- [ ] Test B + +## Screenshots (if applicable) + +If your changes include UI updates to the docs or other applicable repos, please +provide screenshots or GIFs to demonstrate the changes. + +## Additional Information + +Please add any other information that you think might be useful for the reviewer +to know while reviewing this PR. + +Thank you for contributing to the ABsmartly Javascript SDK! diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 88ad5d8..5ee9d34 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,49 +1,51 @@ -# Contributing to the A/B Smartly JavaScript SDK +# Contributing to the ABsmartly Javascript SDK -The A/B Smartly JavaScript SDK is an open source project and we welcome your feedback and contributions. -The information below describes how to build and test the project, and how to submit a pull request. +The ABsmartly Javascript SDK is an open-source project, and we welcome your +feedback and contributions. This guide provides information on how to build +and test the project, and how to submit a pull request. ## Development -### Development process - -1. Fork the repository and create a topic branch from `main` branch. Please use a descriptive name for your branch. -2. While developing, use descriptive messages in your commits. Avoid short or meaningless sentences like: "fix bug". -3. Make sure to add tests for both positive and negative cases. -4. Run the linter script of the project and fix any issues you find. -5. Run the build script and make sure it runs with no errors. -6. Run all tests and make sure there are no failures. -7. `git push` your changes to GitHub within your topic branch. -8. Open a Pull Request from your forked repo and into the `main` branch of the original repository. -9. When creating your PR, please fill out all the fields of the PR template, as applicable, for the project. -10. Check for conflicts once the pull request is created to make sure your PR can be merged cleanly into `main`. -11. Keep an eye out for any feedback or comments from A/B Smartly's SDK team. +### Development Process + +1. **Fork and Branch**: Fork the repository and create a topic branch from the + `main` branch. Use a descriptive name for your branch. +2. **Commit Messages**: Use descriptive commit messages. Avoid short or vague + messages like "fix bug". +3. **Testing**: Add tests for both positive and negative cases to ensure + comprehensive coverage. +4. **Linting**: Run the linter script and fix any issues. This helps maintain + code quality and consistency. +5. **Building**: Run the build script to ensure it completes without errors. +6. **Testing**: Run all tests to ensure there are no failures. +7. **Push Changes**: Push your changes to GitHub in your topic branch. +8. **Pull Request**: Open a pull request from your forked repo into the `main` + branch of the original repository. +9. **PR Template**: Fill out all applicable fields in the pull request template. +10. **Conflict Check**: Ensure there are no conflicts with the `main` branch + when creating the pull request. +11. **Feedback**: Monitor your pull request for any feedback or comments from + the ABsmartly SDK team. ### Building the SDK -For widespread use of the SDK with different environments and module formats, we have three different builds: -* A bundled **UMD** file for browsers (IE 10+). -* A **ES2015** modules compatible build. -* A **CommonJS** modules compatible build. - -The different builds can be generated all at once with the command `npm run build`. Refer to [package.json](package.json) for more insight on the build scripts. - -### Running tests - -The project includes unit tests for both browser and Node.js environments. - -All tests can be run at once with the command `npm run test`. +```bash +npm run build +``` -For additional testing scripts or to get more insight on how these work, please refer to our [package.json](package.json) file. +### Running Tests -### Linting and other useful checks +```bash +npm run test +``` -Consider running the linter script (`npm run lint`) and fixing any issues before pushing your changes. +## Contact -If you want to debug your changes consuming it from a test application, you could: -- For browsers, import the **UMD** bundle from an HTML document. To debug you can use the browser dev tools. -- For Node, you could use symlinks via [npm link command](https://docs.npmjs.com/cli/link.html) and then import the package as usual. To debug you could use the [Node inspector](https://nodejs.org/en/docs/guides/debugging-getting-started/). +If you have any questions or need further assistance, you can reach us at + or on your company's dedicated ABsmartly Slack Connect +channel. -# Contact +--- -If you have any other questions or need to contact us directly we can be reached at sdk@absmartly.com +Thank you for contributing to the ABsmartly Javascript SDK! Your efforts help us +improve and grow our open-source community. diff --git a/LICENSE b/LICENSE index 57bc88a..a023308 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -186,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2024 ABsmartly Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 05e021b..d04c28f 100644 --- a/README.md +++ b/README.md @@ -1,301 +1,83 @@ -# A/B Smartly SDK [![npm version](https://badge.fury.io/js/%40absmartly%2Fjavascript-sdk.svg)](https://badge.fury.io/js/%40absmartly%2Fjavascript-sdk) - -A/B Smartly - JavaScript SDK - -## Compatibility - -The A/B Smartly Javascript SDK is an isomorphic library for Node.js (CommonJS and ES6) and browsers (UMD). - -It's supported on Node.js version 6.x and npm 3.x or later. - -It's supported on IE 10+ and all the other major browsers. - -**Note**: IE 10 does not natively support Promises. -If you target IE 10, you must include a polyfill like [es6-promise](https://www.npmjs.com/package/es6-promise) or [rsvp](https://www.npmjs.com/package/rsvp). + +

+ ABsmartly logo +

+ +# ABsmartly Javascript SDK + +Welcome to the Javascript SDK from ABsmartly! This SDK allows you to integrate +Feature Flagging and A/B testing seamlessly into your applications. + +## Table of Contents + +- [About ABsmartly](#about-absmartly) +- [Installation](#installation) + - [npm](#npm) + - [yarn](#yarn) + - [pnpm](#pnpm) +- [Usage](#usage) +- [Contributing](#contributing) +- [License](#license) +- [Support](#support) + +## About ABsmartly + +ABsmartly is a platform that enables you to run A/B tests across your +applications to optimize and improve user experiences. For more information +about our platform and services, please visit our +[website](https://www.absmartly.com) to request a demo. ## Installation -#### npm - -```shell -npm install @absmartly/javascript-sdk --save -``` - -#### Import in your Javascript application -```javascript -const absmartly = require('@absmartly/javascript-sdk'); -// OR with ES6 modules: -import absmartly from '@absmartly/javascript-sdk'; -``` - - -#### Directly in the browser -You can include an optimized and pre-built package directly in your HTML code through [unpkg.com](https://www.unpkg.com). - -Simply add the following code to your `head` section to include the latest published version. -```html - -``` +To install the Javascript SDK, simply use the following snippet: -## Getting Started +### npm -Please follow the [installation](#installation) instructions before trying the following code: - -#### Initialization -This example assumes an Api Key, an Application, and an Environment have been created in the A/B Smartly web console. -```javascript -// somewhere in your application initialization code -const sdk = new absmartly.SDK({ - endpoint: 'https://sandbox.absmartly.io/v1', - apiKey: process.env.ABSMARTLY_API_KEY, - environment: process.env.NODE_ENV, - application: process.env.APPLICATION_NAME, -}); -``` - -#### Creating a new Context with raw promises -```javascript -// define a new context request -const request = { - units: { - session_id: '5ebf06d8cb5d8137290c4abb64155584fbdb64d8', - }, -}; - -// create context with raw promises -const context = sdk.createContext(request); - -context.ready().then((response) => { - console.log("ABSmartly Context ready!") -}).catch((error) => { - console.log(error); -}); -``` - -#### Creating a new Context with async/await -```javascript -// define a new context request -const request = { - units: { - session_id: '5ebf06d8cb5d8137290c4abb64155584fbdb64d8', - }, -}; - -// create context with raw promises -const context = sdk.createContext(request); - -try { - await context.ready(); - console.log("ABSmartly Context ready!") -} catch (error) { - console.log(error); -} -``` - -#### Creating a new Context with pre-fetched data -When doing full-stack experimentation with A/B Smartly, we recommend creating a context only once on the server-side. -Creating a context involves a round-trip to the A/B Smartly event collector. -We can avoid repeating the round-trip on the client-side by sending the server-side data embedded in the first document, for example, by rendering it on the template. -Then we can initialize the A/B Smartly context on the client-side directly with it. - -```html - - - -``` - -#### Setting extra units for a context -You can add additional units to a context by calling the `unit()` or the `units()` method. -This method may be used for example, when a user logs in to your application, and you want to use the new unit type to the context. -Please note that **you cannot override an already set unit type** as that would be a change of identity, and will throw an exception. In this case, you must create a new context instead. -The `unit()` and `units()` methods can be called before the context is ready. - -```javascript -context.unit('db_user_id', 1000013); - -// or -context.units({ - db_user_id: 1000013, -}); -``` - -#### Setting context attributes -The `attribute()` and `attributes()` methods can be called before the context is ready. -```javascript -context.attribute('user_agent', navigator.userAgent); - -context.attributes({ - customer_age: 'new_customer', -}); -``` - -#### Selecting a treatment -```javascript -if (context.treament("exp_test_experiment") == 0) { - // user is in control group (variant 0) -} else { - // user is in treatment group -} -``` - -#### Tracking a goal achievement -Goals are created in the A/B Smartly web console. -```javascript -context.track("payment", { item_count: 1, total_amount: 1999.99 }); -``` - -#### Publishing pending data -Sometimes it is necessary to ensure all events have been published to the A/B Smartly collector, before proceeding. -One such case is when the user is about to navigate away right before being exposed to a treatment. -You can explicitly call the `publish()` method, which returns a promise, before navigating away. -```javascript -await context.publish().then(() => { - window.location = "https://www.absmartly.com" -}) -``` - -#### Finalizing -The `finalize()` method will ensure all events have been published to the A/B Smartly collector, like `publish()`, and will also "seal" the context, throwing an error if any method that could generate an event is called. -```javascript -await context.finalize().then(() => { - window.location = "https://www.absmartly.com" -}) -``` - -#### Refreshing the context with fresh experiment data -For long-running single-page-applications (SPA), the context is usually created once when the application is first reached. -However, any experiments being tracked in your production code, but started after the context was created, will not be triggered. -To mitigate this, we can use the `refreshInterval` option when creating the context. - -```javascript -const request = { - units: { - session_id: '5ebf06d8cb5d8137290c4abb64155584fbdb64d8', - }, -}; - -const context = sdk.createContext(request, { - refreshInterval: 5 * 60 * 1000 -}); +```bash +npm install @absmartly/javascript-sdk --save ``` -Alternatively, the `refresh()` method can be called manually. -The `refresh()` method pulls updated experiment data from the A/B Smartly collector and will trigger recently started experiments when `treatment()` is called again. -```javascript -setTimeout(async () => { - try { - context.refresh(); - } catch(error) { - console.error(error); - } -}, 5 * 60 * 1000); -``` +### yarn -#### Using a custom Event Logger -The A/B Smartly SDK can be instantiated with an event logger used for all contexts. -In addition, an event logger can be specified when creating a particular context, in the `createContext` call options. -The example below illustrates this with the implementation of the default event logger, used if none is specified. -```javascript -const sdk = new absmartly.SDK({ - endpoint: 'https://sandbox-api.absmartly.com/v1', - apiKey: process.env.ABSMARTLY_API_KEY, - environment: process.env.NODE_ENV, - application: process.env.APPLICATION_NAME, - eventLogger: (context, eventName, data) => { - if (eventName == "error") { - console.error(data); - } - }, -}); +```bash +yarn add @absmartly/javascript-sdk ``` -The data parameter depends on the type of event. -Currently, the SDK logs the following events: - -| eventName | when | data | -|:---: |---|---| -| `"error"` | `Context` receives an error | error object thrown | -| `"ready"` | `Context` turns ready | data used to initialize the context | -| `"refresh"` | `Context.refresh()` method succeeds | data used to refresh the context | -| `"publish"` | `Context.publish()` method succeeds | data sent to the A/B Smartly event collector | -| `"exposure"` | `Context.treatment()` method succeeds on first exposure | exposure data enqueued for publishing | -| `"goal"` | `Context.track()` method succeeds | goal data enqueued for publishing | -| `"finalize"` | `Context.finalize()` method succeeds the first time | undefined | +### pnpm - -#### Peek at treatment variants -Although generally not recommended, it is sometimes necessary to peek at a treatment without triggering an exposure. -The A/B Smartly SDK provides a `peek()` method for that. - -```javascript -if (context.peek("exp_test_experiment") == 0) { - // user is in control group (variant 0) -} else { - // user is in treatment group -} +```bash +pnpm add @absmartly/javascript-sdk ``` -#### Overriding treatment variants -During development, for example, it is useful to force a treatment for an experiment. This can be achieved with the `override()` and/or `overrides()` methods. -The `override()` and `overrides()` methods can be called before the context is ready. -```javascript - context.override("exp_test_experiment", 1); // force variant 1 of treatment - context.overrides({ - exp_test_experiment: 1, - exp_another_experiment: 0, - }); -``` +## Usage -#### HTTP request timeout -It is possible to set a timeout per individual HTTP request, overriding the global timeout set for all request when instantiating the SDK object. +Comprehensive documentation for this SDK is available at +[docs.absmartly.com](https://docs.absmartly.com/docs/SDK-Documentation/getting-started). +There, you will find detailed guides, examples and API references to help you +get started. -Here is an example of setting a timeout only for the createContext request. +## Contributing -```javascript -const context = sdk.createContext(request, { - refreshInterval: 5 * 60 * 1000 -}, { - timeout: 1500 -}); -``` +We welcome contributions from the community and our customers! If you'd like to contribute, +read the [Contributing Guide](./CONTRIBUTING.md) for more information. -#### HTTP Request cancellation -Sometimes it is useful to cancel an inflight HTTP request, for example, when the user is navigating away. The A/B Smartly SDK also supports a cancellation via an `AbortSignal`. An implementation of AbortController is provided for older platforms, but will use the native implementation where available. +## License -Here is an example of a cancellation scenario. +This project is licensed under the Apache 2.0 license. See the +[LICENSE](./LICENSE) file for details. -```javascript -const controller = new absmartly.AbortController(); -const context = sdk.createContext(request, { - refreshInterval: 5 * 60 * 1000 -}, { - signal: controller.signal -}); +## Support -// abort request if not ready after 1500ms -const timeoutId = setTimeout(() => controller.abort(), 1500); - -await context.ready(); - -clearTimeout(timeoutId); -``` +If you encounter any issues or have any questions, please reach out to us at +, open an issue on GitHub, or reach out to us on your +company's dedicated ABsmartly Slack Connect channel. +--- -## About A/B Smartly -**A/B Smartly** is the leading provider of state-of-the-art, on-premises, full-stack experimentation platforms for engineering and product teams that want to confidently deploy features as fast as they can develop them. -A/B Smartly's real-time analytics helps engineering and product teams ensure that new features will improve the customer experience without breaking or degrading performance and/or business metrics. +Happy Experimenting! -### Have a look at our growing list of clients and SDKs: -- [Java SDK](https://www.github.com/absmartly/java-sdk) -- [JavaScript SDK](https://www.github.com/absmartly/javascript-sdk) -- [PHP SDK](https://www.github.com/absmartly/php-sdk) -- [Swift SDK](https://www.github.com/absmartly/swift-sdk) -- [Vue2 SDK](https://www.github.com/absmartly/vue2-sdk) +The ABsmartly Team