Skip to content

Commit 5fd4280

Browse files
authored
feat(node-sdk): improved flag events (#307)
This PR improves the handling of check/evaluate events in the age of `remote config`. Fixes some additional small nagging issues along the way.
1 parent 2029f91 commit 5fd4280

70 files changed

Lines changed: 1386 additions & 2688 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs.sh

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,46 @@ typedoc
1515
# We can fix this by removing the number at the end of the anchor.
1616
SEDCOMMAND='s/globals.md#(.*)-[0-9]+/globals.md#\1/g'
1717

18-
FILES=$(find dist/docs/@bucketco -name "globals.md")
18+
# Find all markdown files including globals.md
19+
FILES=$(find dist/docs/@bucketco -name "*.md")
1920

21+
echo "Processing markdown files..."
2022
for file in $FILES
2123
do
22-
sed -r $SEDCOMMAND $file > $file.fixed
23-
rm $file
24-
mv $file.fixed $file
24+
echo "Processing $file..."
25+
26+
# Fix anchor links in globals.md files
27+
if [[ "$file" == *"globals.md" ]]; then
28+
sed -r "$SEDCOMMAND" "$file" > "$file.fixed"
29+
rm "$file"
30+
mv "$file.fixed" "$file"
31+
fi
32+
33+
# Create a temporary file for processing
34+
tmp_file="${file}.tmp"
35+
36+
# Process NOTE blocks - handle multi-line
37+
awk '
38+
BEGIN { in_block = 0; content = ""; }
39+
/^> \[!NOTE\]/ { in_block = 1; print "{% hint style=\"info\" %}"; next; }
40+
/^> \[!TIP\]/ { in_block = 1; print "{% hint style=\"success\" %}"; next; }
41+
/^> \[!IMPORTANT\]/ { in_block = 1; print "{% hint style=\"warning\" %}"; next; }
42+
/^> \[!WARNING\]/ { in_block = 1; print "{% hint style=\"warning\" %}"; next; }
43+
/^> \[!CAUTION\]/ { in_block = 1; print "{% hint style=\"danger\" %}"; next; }
44+
in_block && /^>/ {
45+
content = content substr($0, 3) "\n";
46+
next;
47+
}
48+
in_block && !/^>/ {
49+
printf "%s", content;
50+
print "{% endhint %}";
51+
in_block = 0;
52+
content = "";
53+
}
54+
!in_block { print; }
55+
' "$file" > "$tmp_file"
56+
57+
mv "$tmp_file" "$file"
2558
done
59+
60+
echo "Processing complete!"

packages/browser-sdk/README.md

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,19 @@ const bucketClient = new BucketClient({ publishableKey, user, company });
2727

2828
await bucketClient.initialize();
2929

30-
const {
31-
isEnabled,
32-
config: { payload: question },
33-
track,
34-
requestFeedback,
35-
} = bucketClient.getFeature("huddle");
30+
const { isEnabled, track, requestFeedback } = bucketClient.getFeature("huddle");
3631

3732
if (isEnabled) {
38-
// Show feature. When retrieving `isEnabled` the client automatically
33+
// show feature. When retrieving `isEnabled` the client automatically
3934
// sends a "check" event for the "huddle" feature which is shown in the
4035
// Bucket UI.
4136

4237
// On usage, call `track` to let Bucket know that a user interacted with the feature
4338
track();
4439

45-
// The `payload` is a user-supplied JSON in Bucket that is dynamically picked
46-
// out depending on the user/company.
47-
const question = payload?.question ?? "Tell us what you think of Huddles";
48-
4940
// Use `requestFeedback` to create "Send feedback" buttons easily for specific
5041
// features. This is not related to `track` and you can call them individually.
51-
requestFeedback({ title: question });
42+
requestFeedback({ title: "Tell us what you think of Huddles" });
5243
}
5344

5445
// `track` just calls `bucketClient.track(<featureKey>)` to send an event using the same feature key
@@ -147,7 +138,6 @@ To retrieve features along with their targeting information, use `getFeature(key
147138
const huddle = bucketClient.getFeature("huddle");
148139
// {
149140
// isEnabled: true,
150-
// config: { key: "zoom", payload: { ... } },
151141
// track: () => Promise<Response>
152142
// requestFeedback: (options: RequestFeedbackData) => void
153143
// }
@@ -161,7 +151,6 @@ const features = bucketClient.getFeatures();
161151
// huddle: {
162152
// isEnabled: true,
163153
// targetingVersion: 42,
164-
// config: ...
165154
// }
166155
// }
167156
```
@@ -170,35 +159,7 @@ const features = bucketClient.getFeatures();
170159
by down-stream clients, like the React SDK.
171160

172161
Note that accessing `isEnabled` on the object returned by `getFeatures` does not automatically
173-
generate a `check` event, contrary to the `isEnabled` property on the object returned by `getFeature`.
174-
175-
### Remote config
176-
177-
Similar to `isEnabled`, each feature has a `config` property. This configuration is managed from within Bucket.
178-
It is managed similar to the way access to features is managed, but instead of the binary `isEnabled` you can have
179-
multiple configuration values which are given to different user/companies.
180-
181-
```ts
182-
const features = bucketClient.getFeatures();
183-
// {
184-
// huddle: {
185-
// isEnabled: true,
186-
// targetingVersion: 42,
187-
// config: {
188-
// key: "gpt-3.5",
189-
// payload: { maxTokens: 10000, model: "gpt-3.5-beta1" }
190-
// }
191-
// }
192-
// }
193-
```
194-
195-
The `key` is always present while the `payload` is a optional JSON value for arbitrary configuration needs.
196-
If feature has no configuration or, no configuration value was matched against the context, the `config` object
197-
will be empty, thus, `key` will be `undefined`. Make sure to check against this case when trying to use the
198-
configuration in your application.
199-
200-
Just as `isEnabled`, accessing `config` on the object returned by `getFeatures` does not automatically
201-
generate a `check` event, contrary to the `config` property on the object returned by `getFeature`.
162+
generate a `check` event, contrary to the `isEnabled` property on the object return from `getFeature`.
202163

203164
### Tracking feature usage
204165

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Bucket feature management</title>
7+
</head>
8+
<body>
9+
<span id="loading">Loading...</span>
10+
11+
<script>
12+
const urlParams = new URLSearchParams(window.location.search);
13+
const publishableKey = urlParams.get("publishableKey");
14+
const featureKey = urlParams.get("featureKey") ?? "huddles";
15+
</script>
16+
<div id="start-huddle" style="display: none">
17+
<button onClick="bucket.track(featureKey)">Click me</button>
18+
<button onClick="bucket.requestFeedback({featureKey})">
19+
Give feedback!
20+
</button>
21+
</div>
22+
23+
<script src="../dist/bucket-browser-sdk.umd.js"></script>
24+
<script>
25+
const bucket = new BucketBrowserSDK.BucketClient({
26+
publishableKey,
27+
user: { id: "42" },
28+
company: { id: "1" },
29+
});
30+
31+
bucket.initialize().then(() => {
32+
console.log("Bucket initialized");
33+
document.getElementById("loading").style.display = "none";
34+
const { isEnabled, track, requestFeedback } =
35+
bucket.getFeature("huddles");
36+
if (isEnabled) {
37+
// show the start-huddle button
38+
document.getElementById("start-huddle").style.display = "block";
39+
}
40+
});
41+
</script>
42+
</body>
43+
</html>

packages/browser-sdk/example/typescript/app.ts

Lines changed: 0 additions & 51 deletions
This file was deleted.

packages/browser-sdk/example/typescript/index.html

Lines changed: 0 additions & 23 deletions
This file was deleted.

packages/browser-sdk/index.html

Lines changed: 0 additions & 71 deletions
This file was deleted.

packages/browser-sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@bucketco/browser-sdk",
3-
"version": "3.0.0-alpha.2",
3+
"version": "2.5.2",
44
"packageManager": "yarn@4.1.1",
55
"license": "MIT",
66
"repository": {

0 commit comments

Comments
 (0)