Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Unleash/unleash-proxy-client-js
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.5.1
Choose a base ref
...
head repository: Unleash/unleash-proxy-client-js
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref

Commits on Jul 19, 2024

  1. Copy the full SHA
    0eb1c3b View commit details

Commits on Jul 22, 2024

  1. v3.5.2

    GitHub Actions Bot committed Jul 22, 2024
    Copy the full SHA
    dc3aa0f View commit details

Commits on Aug 6, 2024

  1. feat: prevent fetch on load (#224)

    New option `togglesStorageTTL` that prevents fetching the flags if they are up to date.
    
    ---------
    
    Co-authored-by: Jérémie Richardeau <jeremie@wanteeed.com>
    Co-authored-by: Florent <florent@wanteeed.com>
    Co-authored-by: Florent-Wanteeed <98741168+Florent-Wanteeed@users.noreply.github.com>
    Co-authored-by: Ivar Conradi Østhus <ivar@getunleash.ai>
    5 people authored Aug 6, 2024
    Copy the full SHA
    c2b4145 View commit details
  2. feat: configurable storage key (#225)

    Co-authored-by: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com>
    kwasniew and Tymek authored Aug 6, 2024
    Copy the full SHA
    8300c98 View commit details
  3. v3.6.0-beta.0

    GitHub Actions Bot committed Aug 6, 2024
    Copy the full SHA
    a1a0e03 View commit details

Commits on Aug 14, 2024

  1. Copy the full SHA
    4b58250 View commit details
  2. v3.6.0-beta.1

    GitHub Actions Bot committed Aug 14, 2024
    Copy the full SHA
    1d48c5d View commit details

Commits on Aug 29, 2024

  1. v3.6.0

    GitHub Actions Bot committed Aug 29, 2024
    Copy the full SHA
    81903aa View commit details

Commits on Sep 4, 2024

  1. Copy the full SHA
    d394b41 View commit details
  2. v3.6.1

    GitHub Actions Bot committed Sep 4, 2024
    Copy the full SHA
    075d119 View commit details

Commits on Oct 16, 2024

  1. Copy the full SHA
    18621fc View commit details
  2. Update README.md (#231)

    kwasniew authored Oct 16, 2024
    Copy the full SHA
    304dd58 View commit details

Commits on Dec 22, 2024

  1. chore(deps): bump cross-spawn from 7.0.3 to 7.0.6 (#233)

    Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6.
    - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md)
    - [Commits](moxystudio/node-cross-spawn@v7.0.3...v7.0.6)
    
    ---
    updated-dependencies:
    - dependency-name: cross-spawn
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Dec 22, 2024
    Copy the full SHA
    e7b4d4e View commit details
  2. Update README.md (#234)

    Co-authored-by: Ivar Conradi Østhus <ivar@getunleash.io>
    alvinometric and ivarconr authored Dec 22, 2024
    Copy the full SHA
    1bf7223 View commit details

Commits on Jan 8, 2025

  1. feat(1 3223): add client identification headers (#235)

    This PR adds client identification headers to the feature and metrics calls that the client makes to Unleash. The headers are:
    - `x-unleash-appname`: the name of the application that is using the client
    - `x-unleash-connection-id`: a unique identifier for the current instance of the client
    - `x-unleash-sdk`: sdk information in the format `unleash-js@<version>`
    thomasheartman authored Jan 8, 2025
    Copy the full SHA
    3615f15 View commit details

Commits on Jan 9, 2025

  1. Copy the full SHA
    4a40951 View commit details
  2. Copy the full SHA
    3a12d52 View commit details

Commits on Jan 14, 2025

  1. Copy the full SHA
    97e6641 View commit details

Commits on Jan 15, 2025

  1. v3.7.0

    GitHub Actions Bot committed Jan 15, 2025
    Copy the full SHA
    fdb7d84 View commit details
  2. meta: pin workflow version again (#236)

    This commit re-pins the workflow version for the release template
    reference. It uses an assumed 2.0 which is what we'd need to bump it
    to for changing the parameters.
    thomasheartman authored Jan 15, 2025
    Copy the full SHA
    df7b6f0 View commit details

Commits on Jan 16, 2025

  1. fix: embed version at compile time (#237)

    Removes requiring version at runtime with require: 3615f15#diff-258035e5968f6bf645400d417f310218d7d9a9a10606a3c34e7f55db193f58f3R3
    
    Instead we're using the rollup replace plugin to read the version at build time and replace __VERSION__ placeholder with the actual version number.
    
    As a result other packages depending on this one don't need to understand require calls and also we're not exposing the whole package.json file at runtime.
    
    To verify my claim above you can build the package and check the build directory after this change vs before this change.
    kwasniew authored Jan 16, 2025
    Copy the full SHA
    b2e385d View commit details
  2. v3.7.1

    GitHub Actions Bot committed Jan 16, 2025
    Copy the full SHA
    e204714 View commit details
  3. chore(1-3230): use homebrew version of uuid generation (#240)

    The one from the uuid library relies on an underlying crypto library
    which doesn't exist at least in certain GitHub runners and may also
    cause issues for react native applications.
    
    This impl sidesteps that issue.
    
    
    The same uuid generation method that we're cutting out here is also being used in src/events-handler.ts. However, because we haven't received any complaints about that, I'll leave it in.
    thomasheartman authored Jan 16, 2025
    Copy the full SHA
    40daee5 View commit details
  4. v3.7.2

    GitHub Actions Bot committed Jan 16, 2025
    Copy the full SHA
    bf26e94 View commit details

Commits on Jan 31, 2025

  1. Copy the full SHA
    80af67f View commit details
  2. v3.7.3

    GitHub Actions Bot committed Jan 31, 2025
    Copy the full SHA
    f69227e View commit details
Showing with 1,846 additions and 951 deletions.
  1. +4 −3 .github/workflows/release.yml
  2. +1 −0 .gitignore
  3. +24 −19 README.md
  4. +1 −1 examples/README.md
  5. +5 −3 package.json
  6. +8 −0 rollup.config.mjs
  7. +637 −9 src/index.test.ts
  8. +135 −28 src/index.ts
  9. +42 −2 src/metrics.test.ts
  10. +13 −12 src/metrics.ts
  11. +12 −0 src/storage-provider-local.test.ts
  12. +5 −1 src/storage-provider-local.ts
  13. +180 −1 src/util.test.ts
  14. +88 −0 src/util.ts
  15. +14 −0 src/uuidv4.ts
  16. +1 −0 src/version.ts
  17. +676 −872 yarn.lock
7 changes: 4 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
version:
description: New version semver
description: New version semver (e.g. 3.7.0)
required: true
type: string
tag:
@@ -15,10 +15,11 @@ on:

jobs:
from-template:
uses: Unleash/.github/.github/workflows/npm-release.yml@v1.1.0
uses: Unleash/.github/.github/workflows/npm-release.yml@v2.0.0
with:
version: ${{ github.event.inputs.version }}
tag: ${{ github.event.inputs.tag }}
secrets:
GH_ACCESS_TOKEN: ${{ secrets.GH_TOKEN }}
NPM_ACCESS_TOKEN: ${{ secrets.NPM_TOKEN }}
UNLEASH_BOT_APP_ID: ${{ secrets.UNLEASH_BOT_APP_ID }}
UNLEASH_BOT_PRIVATE_KEY: ${{ secrets.UNLEASH_BOT_PRIVATE_KEY }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -3,3 +3,4 @@ node_modules/
.vscode/
coverage/
.idea
.DS_Store
43 changes: 24 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# Unleash Proxy Client for the browser (JS)

The JavaScript proxy client is a tiny Unleash client written in JavaScript without any external dependencies (except from browser APIs). This client stores toggles relevant for the current user in `localStorage` and synchronizes with Unleash (the [Unleash front-end API](https://docs.getunleash.io/reference/front-end-api) _or_ the [Unleash proxy](https://docs.getunleash.io/reference/unleash-proxy)) in the background. Because toggles are stored in the user's browser, the client can use them to bootstrap itself the next time the user visits the same web page.
The JavaScript client is a tiny Unleash client written in JavaScript without any external dependencies (except from browser APIs). This client stores toggles relevant for the current user in `localStorage` and synchronizes with Unleash (the [Unleash front-end API](https://docs.getunleash.io/reference/front-end-api) _or_ [Unleash edge](https://docs.getunleash.io/reference/unleash-edge)) in the background. Because toggles are stored in the user's browser, the client can use them to bootstrap itself the next time the user visits the same web page.

This client expect `fetch` to be available. If you need to support older
browsers you should probably use the [fetch polyfill](https://github.com/github/fetch).
This client expect `fetch` to be available.

## Frameworks supported

This package is not tied to any framework, but can be used together most popular frameworks, examples:

- [Unleash React SDK](https://docs.getunleash.io/sdks/proxy-react)
- [Unleash React SDK](https://docs.getunleash.io/reference/sdks/react)
- [React](https://reactjs.org/)
- [React Native](https://reactnative.dev/)
- [Angular JS](https://angularjs.org/)
@@ -28,7 +27,7 @@ npm install unleash-proxy-client

---

💡 **TIP**: As a client-side SDK, this SDK requires you to connect to either an Unleash proxy or to the Unleash front-end API. Refer to the [connection options section](#connection-options) for more information.
💡 **TIP**: As a client-side SDK, this SDK requires you to connect to either Unleash Edge or to the Unleash front-end API. Refer to the [connection options section](#connection-options) for more information.

---

@@ -51,18 +50,18 @@ unleash.start();

To connect this SDK to your Unleash instance's [front-end API](https://docs.getunleash.io/reference/front-end-api), use the URL to your Unleash instance's front-end API (`<unleash-url>/api/frontend`) as the `url` parameter. For the `clientKey` parameter, use a `FRONTEND` token generated from your Unleash instance. Refer to the [_how to create API tokens_](https://docs.getunleash.io/how-to/how-to-create-api-tokens) guide for the necessary steps.

To connect this SDK to the [Unleash proxy](https://docs.getunleash.io/reference/unleash-proxy), use the proxy's URL and a [proxy client key](https://docs.getunleash.io/reference/api-tokens-and-client-keys#proxy-client-keys). The [_configuration_ section of the Unleash proxy docs](https://docs.getunleash.io/reference/unleash-proxy#configuration) contains more info on how to configure client keys for your proxy.
This SDK can also be used with [Unleash Edge](https://docs.getunleash.io/reference/unleash-edge).

### Step 3: Let the client synchronize

You should wait for the client's `ready` or `initialized` events before you start working with it. Before it's ready, the client might not report the correct state for your features.

```js
unleash.on('ready', () => {
if (unleash.isEnabled('proxy.demo')) {
console.log('proxy.demo is enabled');
if (unleash.isEnabled('js.demo')) {
console.log('js.demo is enabled');
} else {
console.log('proxy.demo is disabled');
console.log('js.demo is disabled');
}
});
```
@@ -74,7 +73,7 @@ The difference between the events is described in the [section on available even
Once the client is ready, you can start checking features in your application. Use the `isEnabled` method to check the state of any feature you want:

```js
unleash.isEnabled('proxy.demo');
unleash.isEnabled('js.demo');
```

You can use the `getVariant` method to get the variant of an **enabled feature that has variants**. If the feature is disabled or if it has no variants, then you will get back the [**disabled variant**](https://docs.getunleash.io/reference/feature-toggle-variants#the-disabled-variant)
@@ -117,26 +116,26 @@ The Unleash SDK takes the following options:

| option | required | default | description |
|-------------------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| url | yes | n/a | The Unleash Proxy URL to connect to. E.g.: `https://examples.com/proxy` |
| clientKey | yes | n/a | The Unleash Proxy Secret to be used |
| appName | yes | n/a | The name of the application using this SDK. Will be used as part of the metrics sent to Unleash Proxy. Will also be part of the Unleash Context. |
| url | yes | n/a | The Unleash URL to connect to. E.g.: `https://examples.com/api/front-end` |
| clientKey | yes | n/a | The Unleash API Secret to be used |
| appName | yes | n/a | The name of the application using this SDK. Will be used as part of the metrics sent to Unleash. Will also be part of the Unleash Context. |
| context | no | `{}` | The initial Unleash context. This will be used as the initial context for all feature toggle evaluations. The `appName` and `environment` options will automatically be populated with the values you pass for those options. |
| refreshInterval | no | `30` | How often, in seconds, the SDK should check for updated toggle configuration. If set to 0 will disable checking for updates |
| disableRefresh | no | `false` | If set to true, the client will not check for updated toggle configuration |
| metricsInterval | no | `60` | How often, in seconds, the SDK should send usage metrics back to Unleash Proxy. It will be started after the initial metrics report, which is sent after the configured `metricsIntervalInitial` |
| metricsInterval | no | `60` | How often, in seconds, the SDK should send usage metrics back to Unleash. It will be started after the initial metrics report, which is sent after the configured `metricsIntervalInitial` |
| metricsIntervalInitial | no | `2` | How long the SDK should wait for the first metrics report back to the Unleash API. If you want to disable the initial metrics call you can set it to 0. |
| disableMetrics | no | `false` | Set this option to `true` if you want to disable usage metrics |
| storageProvider | no | `LocalStorageProvider` in browser, `InMemoryStorageProvider` otherwise | Allows you to inject a custom storeProvider |
| fetch | no | `window.fetch` or global `fetch` | Allows you to override the fetch implementation to use. Useful in Node.js environments where you can inject `node-fetch` |
| createAbortController | no | `() => new AbortController()` | Allows you to override the default `AbortController` creation. Used to cancel requests with outdated context. Set it to `() => null` if you don't want to handle it. |
| bootstrap | no | `[]` | Allows you to bootstrap the cached feature toggle configuration. |
| bootstrapOverride | no| `true` | Should the bootstrap automatically override cached data in the local-storage. Will only be used if bootstrap is not an empty array. |
| headerName | no| `Authorization` | Which header the SDK should use to authorize with Unleash / Unleash Proxy. The header will be given the `clientKey` as its value. |
| customHeaders | no| `{}` | Additional headers to use when making HTTP requests to the Unleash proxy. In case of name collisions with the default headers, the `customHeaders` value will be used if it is not `null` or `undefined`. `customHeaders` values that are `null` or `undefined` will be ignored. |
| headerName | no| `Authorization` | Which header the SDK should use to authorize with Unleash / Unleash Edge. The header will be given the `clientKey` as its value. |
| customHeaders | no| `{}` | Additional headers to use when making HTTP requests to Unleash. In case of name collisions with the default headers, the `customHeaders` value will be used if it is not `null` or `undefined`. `customHeaders` values that are `null` or `undefined` will be ignored. |
| impressionDataAll | no| `false` | Allows you to trigger "impression" events for **all** `getToggle` and `getVariant` invocations. This is particularly useful for "disabled" feature toggles that are not visible to frontend SDKs. |
| environment | no | `default` | Sets the `environment` option of the [Unleash context](https://docs.getunleash.io/reference/unleash-context). This does **not** affect the SDK's [Unleash environment](https://docs.getunleash.io/reference/environments). |
| usePOSTrequests | no | `false` | Configures the client to use POST requests instead of GET when requesting enabled features. This is helpful when sensitive information (like user email, when used as a user ID) is passed in the context to avoid leaking it in the URL. NOTE: Post requests are not supported by the frontend api built into Unleash. |

| experimental | no | `{}` | Enabling optional experimentation. `togglesStorageTTL` : How long (Time To Live), in seconds, the toggles in storage are considered valid and should not be fetched on start. If set to 0 will disable expiration checking and will be considered always expired. |

### Listen for updates via the EventEmitter

@@ -145,7 +144,7 @@ This is a neat way to update a single page app when toggle state updates.

```js
unleash.on('update', () => {
const myToggle = unleash.isEnabled('proxy.demo');
const myToggle = unleash.isEnabled('js.demo');
//do something useful
});
```
@@ -155,7 +154,7 @@ unleash.on('update', () => {
- **error** - emitted when an error occurs on init, or when fetch function fails, or when fetch receives a non-ok response object. The error object is sent as payload.
- **initialized** - emitted after the SDK has read local cached data in the storageProvider.
- **ready** - emitted after the SDK has successfully started and performed the initial fetch of flags via the network (Edge, proxy, or front-end API). When bootstrapping, the client can emit this event twice: once when the bootstrapped flags are loaded, and once on first successful connection to Unleash.
- **update** - emitted every time the Unleash Proxy return a new feature toggle configuration. The SDK will emit this event as part of the initial fetch from the SDK.
- **update** - emitted every time Unleash returns a new feature toggle configuration. The SDK will emit this event as part of the initial fetch from the SDK.
- **recovered** - emitted when the SDK has recovered from an error. This event will only be emitted if the SDK has previously emitted an error.
- **sent** - emitted when the SDK has successfully sent metrics to Unleash.

@@ -293,3 +292,9 @@ const unleash = new UnleashClient({
**NOTES: ⚠️**
If `bootstrapOverride` is `true` (by default), any local cached data will be overridden with the bootstrap specified.
If `bootstrapOverride` is `false` any local cached data will not be overridden unless the local cache is empty.

## Manage your own refresh mechanism

You can opt out of the Unleash feature flag auto-refresh mechanism and metrics update by settings the `refreshInterval` and/or `metricsInterval` options to `0`.
In this case, it becomes your responsibility to call `updateToggles` and/or `sendMetrics` methods.
This approach is useful in environments that do not support the `setInterval` API, such as service workers.
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
## Examples

Moved to [unleash-sdk-examples](https://github.com/Unleash/unleash-sdk-examples/tree/main/JavaScript%20Proxy%20SDK)
Moved to [unleash-sdk-examples](https://github.com/Unleash/unleash-sdk-examples/tree/main/JavaScript)
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "unleash-proxy-client",
"version": "3.5.1",
"description": "A browser client that can be used together with the unleash-proxy.",
"version": "3.7.3",
"description": "A browser client that can be used together with Unleash Edge or the Unleash Frontend API.",
"type": "module",
"main": "./build/index.cjs",
"types": "./build/cjs/index.d.ts",
@@ -46,6 +46,7 @@
"@babel/runtime": "^7.23.1",
"@rollup/plugin-commonjs": "^25.0.5",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^6.0.2",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.5",
"@types/jest": "^29.5.5",
@@ -86,5 +87,6 @@
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}
},
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
}
8 changes: 8 additions & 0 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -3,6 +3,10 @@ import nodeResolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import terser from '@rollup/plugin-terser';
import nodePolyfills from 'rollup-plugin-node-polyfills';
import replace from '@rollup/plugin-replace';
import fs from 'fs';

const version = JSON.parse(fs.readFileSync('./package.json', 'UTF-8')).version;

export default {
input: './src/index.ts',
@@ -25,6 +29,10 @@ export default {
}
],
plugins: [
replace({
'__VERSION__': version,
preventAssignment: true
}),
typescript({
compilerOptions: {
lib: ['es5', 'es6', 'dom'],
Loading