Skip to content

Commit a17bdf0

Browse files
cursoragentlaander
andcommitted
feat: Add @reflag/svelte-sdk package
Co-authored-by: lasse <[email protected]>
1 parent c4030e2 commit a17bdf0

33 files changed

+2076
-4
lines changed

packages/svelte-sdk/README.md

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
# Reflag Svelte SDK
2+
3+
The Reflag Svelte SDK provides a simple and intuitive way to integrate feature flags into your Svelte applications. Built on top of the Reflag browser SDK, it offers reactive stores and utilities that work seamlessly with Svelte's reactivity system.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @reflag/svelte-sdk
9+
# or
10+
yarn add @reflag/svelte-sdk
11+
# or
12+
pnpm add @reflag/svelte-sdk
13+
```
14+
15+
## Quick Start
16+
17+
### 1. Set up the Provider
18+
19+
First, initialize the Reflag provider at the root of your application:
20+
21+
```javascript
22+
// main.ts or App.svelte
23+
import { createReflagProvider } from '@reflag/svelte-sdk';
24+
25+
// Initialize the provider
26+
createReflagProvider({
27+
apiKey: 'your-api-key',
28+
user: {
29+
id: 'user-123',
30+
31+
name: 'John Doe'
32+
},
33+
company: {
34+
id: 'company-456',
35+
name: 'Acme Inc'
36+
}
37+
});
38+
```
39+
40+
### 2. Use Feature Flags in Components
41+
42+
```svelte
43+
<script lang="ts">
44+
import { useFlag, useTrack } from '@reflag/svelte-sdk';
45+
46+
// Get a feature flag
47+
const huddleFlag = useFlag('huddle');
48+
const track = useTrack();
49+
50+
function startHuddle() {
51+
// Track the feature usage
52+
huddleFlag.track();
53+
54+
// Your huddle logic here
55+
console.log('Starting huddle...');
56+
}
57+
</script>
58+
59+
{#if $huddleFlag.isEnabled}
60+
<button on:click={startHuddle}>
61+
{$huddleFlag.config.payload?.buttonText || 'Start Huddle'}
62+
</button>
63+
{:else}
64+
<p>Huddle feature is not available</p>
65+
{/if}
66+
```
67+
68+
## API Reference
69+
70+
### Provider
71+
72+
#### `createReflagProvider(props: ReflagProps)`
73+
74+
Creates and initializes the Reflag provider. This should be called once at the root of your application.
75+
76+
**Parameters:**
77+
- `props.apiKey` (string): Your Reflag API key
78+
- `props.user` (object, optional): User context information
79+
- `props.company` (object, optional): Company context information
80+
- `props.otherContext` (object, optional): Additional context information
81+
- `props.debug` (boolean, optional): Enable debug logging
82+
83+
### Stores and Utilities
84+
85+
#### `useFlag(key: string)`
86+
87+
Returns a reactive flag object with the following properties:
88+
89+
- `isEnabled` (Readable<boolean>): Whether the flag is enabled
90+
- `isLoading` (Readable<boolean>): Whether the flag is currently loading
91+
- `config` (Readable<object>): The flag's configuration data
92+
- `track()` (function): Track usage of this flag
93+
- `requestFeedback(options)` (function): Request feedback for this flag
94+
95+
**Example:**
96+
```svelte
97+
<script lang="ts">
98+
import { useFlag } from '@reflag/svelte-sdk';
99+
100+
const myFlag = useFlag('my-feature');
101+
</script>
102+
103+
{#if $myFlag.isLoading}
104+
<p>Loading...</p>
105+
{:else if $myFlag.isEnabled}
106+
<div>Feature is enabled!</div>
107+
<button on:click={() => myFlag.track()}>Use Feature</button>
108+
{:else}
109+
<div>Feature is disabled</div>
110+
{/if}
111+
```
112+
113+
#### `useTrack()`
114+
115+
Returns a function to track custom events.
116+
117+
**Example:**
118+
```svelte
119+
<script lang="ts">
120+
import { useTrack } from '@reflag/svelte-sdk';
121+
122+
const track = useTrack();
123+
124+
function handleClick() {
125+
track('button_clicked', { buttonName: 'CTA Button' });
126+
}
127+
</script>
128+
129+
<button on:click={handleClick}>Click me</button>
130+
```
131+
132+
#### `useClient()`
133+
134+
Returns a readable store containing the current ReflagClient instance.
135+
136+
**Example:**
137+
```svelte
138+
<script lang="ts">
139+
import { useClient } from '@reflag/svelte-sdk';
140+
141+
const client = useClient();
142+
143+
// Access client methods
144+
$: if ($client) {
145+
console.log('Client is ready');
146+
}
147+
</script>
148+
```
149+
150+
#### `useIsLoading()`
151+
152+
Returns a readable store indicating whether the SDK is currently loading.
153+
154+
**Example:**
155+
```svelte
156+
<script lang="ts">
157+
import { useIsLoading } from '@reflag/svelte-sdk';
158+
159+
const isLoading = useIsLoading();
160+
</script>
161+
162+
{#if $isLoading}
163+
<div>Loading flags...</div>
164+
{:else}
165+
<div>Flags loaded!</div>
166+
{/if}
167+
```
168+
169+
#### `useRequestFeedback()`
170+
171+
Returns a function to request feedback from users.
172+
173+
**Example:**
174+
```svelte
175+
<script lang="ts">
176+
import { useRequestFeedback } from '@reflag/svelte-sdk';
177+
178+
const requestFeedback = useRequestFeedback();
179+
180+
function askForFeedback() {
181+
requestFeedback({
182+
flagKey: 'my-feature',
183+
title: 'How was your experience?',
184+
prompt: 'Please let us know how we can improve this feature.'
185+
});
186+
}
187+
</script>
188+
189+
<button on:click={askForFeedback}>Give Feedback</button>
190+
```
191+
192+
#### `useSendFeedback()`
193+
194+
Returns a function to send feedback programmatically.
195+
196+
#### `useUpdateUser()`, `useUpdateCompany()`, `useUpdateOtherContext()`
197+
198+
Return functions to update context information, which will trigger flag re-evaluation.
199+
200+
**Example:**
201+
```svelte
202+
<script lang="ts">
203+
import { useUpdateUser } from '@reflag/svelte-sdk';
204+
205+
const updateUser = useUpdateUser();
206+
207+
function upgradeUser() {
208+
updateUser({ plan: 'premium' });
209+
}
210+
</script>
211+
212+
<button on:click={upgradeUser}>Upgrade to Premium</button>
213+
```
214+
215+
## TypeScript Support
216+
217+
The SDK includes full TypeScript support. You can extend the `Flags` interface to get type-safe flag keys:
218+
219+
```typescript
220+
// types/reflag.d.ts
221+
declare module '@reflag/svelte-sdk' {
222+
interface Flags {
223+
'huddle': {
224+
config: {
225+
payload: {
226+
buttonText: string;
227+
maxParticipants: number;
228+
};
229+
};
230+
};
231+
'file-uploads': {
232+
config: {
233+
payload: {
234+
maxFileSize: number;
235+
allowedTypes: string[];
236+
};
237+
};
238+
};
239+
}
240+
}
241+
```
242+
243+
Now you'll get full type safety:
244+
245+
```svelte
246+
<script lang="ts">
247+
import { useFlag } from '@reflag/svelte-sdk';
248+
249+
// TypeScript knows this returns the correct type
250+
const huddle = useFlag('huddle');
251+
252+
// TypeScript knows config.payload has buttonText and maxParticipants
253+
$: buttonText = $huddle.config.payload?.buttonText || 'Start Huddle';
254+
</script>
255+
```
256+
257+
## Error Handling
258+
259+
The SDK will throw an error if you try to use any of the utilities without first calling `createReflagProvider()`:
260+
261+
```javascript
262+
// This will throw an error
263+
const flag = useFlag('my-flag'); // Error: ReflagProvider is missing
264+
```
265+
266+
Make sure to call `createReflagProvider()` before using any other SDK functions.
267+
268+
## Development
269+
270+
To run the development example:
271+
272+
```bash
273+
cd packages/svelte-sdk
274+
yarn dev
275+
```
276+
277+
This will start a development server with a demo application showing the SDK in action.
278+
279+
## Testing
280+
281+
```bash
282+
yarn test
283+
```
284+
285+
## Building
286+
287+
```bash
288+
yarn build
289+
```
290+
291+
## License
292+
293+
MIT

0 commit comments

Comments
 (0)