@gradual-so/sdk 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -0
- package/package.json +10 -3
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# @gradual-so/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for [Gradual](https://gradual.so) feature flags. Works in Node.js, browsers, and edge runtimes.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @gradual-so/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { createGradual } from '@gradual-so/sdk'
|
|
15
|
+
|
|
16
|
+
const gradual = createGradual({
|
|
17
|
+
apiKey: 'gra_xxx',
|
|
18
|
+
environment: 'production',
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const enabled = await gradual.isEnabled('new-feature')
|
|
22
|
+
|
|
23
|
+
const theme = await gradual.get('theme', { fallback: 'light' })
|
|
24
|
+
// theme is typed as string (inferred from fallback)
|
|
25
|
+
|
|
26
|
+
const limit = await gradual.get('max-items', { fallback: 10 })
|
|
27
|
+
// limit is typed as number
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The SDK initializes automatically. Async methods like `isEnabled` and `get` wait for initialization before evaluating.
|
|
31
|
+
|
|
32
|
+
## User targeting
|
|
33
|
+
|
|
34
|
+
Set user context once, and it applies to all subsequent evaluations:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
gradual.identify({
|
|
38
|
+
userId: 'user-123',
|
|
39
|
+
email: 'eli@example.com',
|
|
40
|
+
plan: 'pro',
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const proFeature = await gradual.isEnabled('pro-feature')
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Override context for a single evaluation:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
const enabled = await gradual.isEnabled('feature', {
|
|
50
|
+
context: { region: 'eu-west' },
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Clear identity:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
gradual.reset()
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Synchronous access
|
|
61
|
+
|
|
62
|
+
For performance-critical paths, use `sync` methods after ensuring the SDK is ready:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
await gradual.ready()
|
|
66
|
+
|
|
67
|
+
const enabled = gradual.sync.isEnabled('feature')
|
|
68
|
+
const theme = gradual.sync.get('theme', { fallback: 'light' })
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`sync` methods throw if the SDK hasn't finished initializing. Use them when you've already awaited `ready()` earlier in your app lifecycle (e.g. server startup, after provider mount).
|
|
72
|
+
|
|
73
|
+
## Refreshing
|
|
74
|
+
|
|
75
|
+
Fetch the latest flag snapshot from the server:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
await gradual.refresh()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API
|
|
82
|
+
|
|
83
|
+
### `createGradual(options)`
|
|
84
|
+
|
|
85
|
+
Creates a new Gradual client. Initializes automatically on creation.
|
|
86
|
+
|
|
87
|
+
| Option | Type | Required | Description |
|
|
88
|
+
|---|---|---|---|
|
|
89
|
+
| `apiKey` | `string` | Yes | Your Gradual API key |
|
|
90
|
+
| `environment` | `string` | Yes | Environment slug (e.g. `production`) |
|
|
91
|
+
| `baseUrl` | `string` | No | Custom API base URL |
|
|
92
|
+
|
|
93
|
+
### Methods
|
|
94
|
+
|
|
95
|
+
| Method | Returns | Description |
|
|
96
|
+
|---|---|---|
|
|
97
|
+
| `isEnabled(key, options?)` | `Promise<boolean>` | Check if a boolean flag is enabled |
|
|
98
|
+
| `get(key, { fallback })` | `Promise<T>` | Get a typed flag value (type inferred from fallback) |
|
|
99
|
+
| `identify(context)` | `void` | Set persistent user context for all evaluations |
|
|
100
|
+
| `reset()` | `void` | Clear the identified user context |
|
|
101
|
+
| `ready()` | `Promise<void>` | Wait for SDK initialization |
|
|
102
|
+
| `isReady()` | `boolean` | Check if SDK has finished initializing |
|
|
103
|
+
| `refresh()` | `Promise<void>` | Fetch the latest flag snapshot |
|
|
104
|
+
| `sync.isEnabled(key, options?)` | `boolean` | Synchronous boolean check (throws if not ready) |
|
|
105
|
+
| `sync.get(key, { fallback })` | `T` | Synchronous value access (throws if not ready) |
|
|
106
|
+
|
|
107
|
+
### Context options
|
|
108
|
+
|
|
109
|
+
Both `isEnabled` and `get` accept an optional `context` object to override the identified context for that evaluation:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
await gradual.get('feature', {
|
|
113
|
+
fallback: 'default',
|
|
114
|
+
context: { teamId: 'team-abc' },
|
|
115
|
+
})
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## React
|
|
119
|
+
|
|
120
|
+
For React apps, use [`@gradual-so/sdk-react`](https://www.npmjs.com/package/@gradual-so/sdk-react) which provides hooks and a provider component built on this SDK.
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradual-so/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Gradual feature flag SDK for TypeScript and JavaScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"sideEffects": false,
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"provenance": true
|
|
28
|
+
},
|
|
25
29
|
"license": "MIT",
|
|
26
30
|
"keywords": [
|
|
27
31
|
"feature-flags",
|
|
@@ -31,18 +35,21 @@
|
|
|
31
35
|
],
|
|
32
36
|
"repository": {
|
|
33
37
|
"type": "git",
|
|
34
|
-
"url": "https://github.com/
|
|
38
|
+
"url": "https://github.com/elijahnikov/gradual",
|
|
35
39
|
"directory": "packages/sdk"
|
|
36
40
|
},
|
|
37
41
|
"scripts": {
|
|
38
42
|
"build": "tsup",
|
|
39
43
|
"clean": "git clean -xdf .cache .turbo dist node_modules",
|
|
40
44
|
"dev": "tsup --watch",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
41
47
|
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
|
|
42
48
|
},
|
|
43
49
|
"devDependencies": {
|
|
44
50
|
"@gradual/tsconfig": "workspace:*",
|
|
45
51
|
"tsup": "^8.5.1",
|
|
46
|
-
"typescript": "catalog:"
|
|
52
|
+
"typescript": "catalog:",
|
|
53
|
+
"vitest": "^4.0.18"
|
|
47
54
|
}
|
|
48
55
|
}
|