Skip to content

Commit 3b923f1

Browse files
committed
feat: add launchDarkly test
1 parent c7081aa commit 3b923f1

7 files changed

+158
-22
lines changed

package-lock.json

+17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@chakra-ui/icons": "2.0.17",
3838
"@chakra-ui/react": "2.1.2",
3939
"@ngneat/falso": "5.3.0",
40+
"@radix-ui/react-icons": "1.2.0",
4041
"@storybook/addon-essentials": "^7.0.0-beta.50",
4142
"@storybook/addon-interactions": "^7.0.0-beta.50",
4243
"@storybook/addon-links": "^7.0.0-beta.50",

src/core/keat.ts

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
import { load } from "./display";
2-
import type {
3-
EvalCtx,
4-
OnEvalApi,
5-
OnPluginInitApi,
6-
onPostEvaluateHook,
7-
Plugin,
8-
} from "./plugin";
2+
import type { EvalCtx, OnEvalApi, OnPluginInitApi, Plugin } from "./plugin";
93
import type {
104
AnyFeatures,
115
Config,
@@ -20,7 +14,7 @@ import { mutable } from "./utils";
2014

2115
export type ExtractFeatures<K> = K extends KeatApi<infer K> ? keyof K : never;
2216

23-
export type Listener = () => void;
17+
export type Listener = (config?: Config) => void;
2418
export type Unsubscribe = () => void;
2519

2620
export function keatCore<TFeatures extends AnyFeatures>({
@@ -40,7 +34,7 @@ export function keatCore<TFeatures extends AnyFeatures>({
4034
config = newConfig;
4135
},
4236
onChange: () => {
43-
listeners.forEach((l) => l());
37+
listeners.forEach((l) => l(config));
4438
},
4539
};
4640

@@ -144,7 +138,7 @@ function evaluateVariate(
144138
plugins: Plugin[],
145139
rule: Rule | undefined
146140
): boolean {
147-
if (!rule) return false;
141+
if (rule === undefined) return false;
148142
return isLiteral(rule)
149143
? plugins.some((p) => {
150144
const matchers = Array.isArray(p.matcher) ? p.matcher : [p.matcher];

src/plugins/featureDisplay.stories.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function RemoteDemo() {
5151
]);
5252
}, [setValue, setRows]);
5353

54-
useIntervalWhen(() => setValue(value + 10), 10);
54+
useIntervalWhen(() => setValue(value + 50), 50);
5555
useIntervalWhen(() => setDisplayValue(displayValue + 250), 250);
5656

5757
return (

src/plugins/launchdarkly.stories.tsx

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { PlayIcon, StopIcon } from "@radix-ui/react-icons";
2+
import {
3+
Center,
4+
Heading,
5+
HStack,
6+
Table,
7+
TableContainer,
8+
Tbody,
9+
Td,
10+
Text,
11+
Th,
12+
Thead,
13+
Tr,
14+
VStack,
15+
} from "@chakra-ui/react";
16+
import { Meta, StoryObj } from "@storybook/react";
17+
import React, { useMemo } from "react";
18+
import { keatReact } from "../react/KeatReact";
19+
import { launchDarkly } from "./launchdarkly";
20+
21+
type Props = {
22+
clientId: string;
23+
};
24+
25+
function LaunchDarklyDemo({ clientId }: Props) {
26+
const { FeatureBoundary } = useMemo(() => {
27+
return keatReact({
28+
plugins: [launchDarkly(clientId)],
29+
features: { demo: false },
30+
});
31+
}, [clientId]);
32+
33+
return (
34+
<VStack width="100%">
35+
<VStack padding="6" alignItems="start" width="100%" spacing="3">
36+
<HStack>
37+
<Heading>LaunchDarkly</Heading>
38+
</HStack>
39+
<Text>Use Keat's interface instead of LaunchDarkly.</Text>
40+
</VStack>
41+
42+
<TableContainer width="100%">
43+
<Table variant="striped" colorScheme="orange">
44+
<Thead>
45+
<Tr>
46+
<Th>Feature</Th>
47+
<Th>Demo Element</Th>
48+
</Tr>
49+
</Thead>
50+
51+
<Tbody>
52+
<Tr key="demo">
53+
<Td>Demo</Td>
54+
<Td>
55+
<FeatureBoundary name="demo" fallback={<Fallback />}>
56+
<Remote />
57+
</FeatureBoundary>
58+
</Td>
59+
</Tr>
60+
</Tbody>
61+
</Table>
62+
</TableContainer>
63+
</VStack>
64+
);
65+
}
66+
67+
function Invisible() {
68+
return (
69+
<Center
70+
borderRadius="md"
71+
color="gray"
72+
border="dashed"
73+
width="10"
74+
height="10"
75+
/>
76+
);
77+
}
78+
79+
function Fallback() {
80+
return (
81+
<Center
82+
borderRadius="md"
83+
color="red.600"
84+
border="solid"
85+
width="10"
86+
height="10"
87+
>
88+
<StopIcon />
89+
</Center>
90+
);
91+
}
92+
93+
function Remote() {
94+
return (
95+
<Center
96+
borderRadius="md"
97+
color="green.600"
98+
border="solid"
99+
width="10"
100+
height="10"
101+
>
102+
<PlayIcon />
103+
</Center>
104+
);
105+
}
106+
107+
/* * * * * * * * * * * * * *
108+
* Stories
109+
* * * * * * * * * * * * * */
110+
const meta: Meta<typeof LaunchDarklyDemo> = {
111+
title: "Integrations/LaunchDarkly",
112+
component: LaunchDarklyDemo,
113+
};
114+
115+
export default meta;
116+
type Story = StoryObj<typeof meta>;
117+
118+
export const Default: Story = {};

src/plugins/launchdarkly.ts

+11-10
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,24 @@ import {
44
LDContext,
55
LDFlagChangeset,
66
LDFlagSet,
7+
LDOptions,
78
} from "launchdarkly-js-client-sdk";
89
import { isAny, Plugin } from "../core/plugin";
910

10-
type LaunchDarklyPluginOptions = {
11-
clientId: string;
12-
};
13-
14-
export const remoteConfig = (options: LaunchDarklyPluginOptions): Plugin => {
11+
export const launchDarkly = (clientId: string, options?: LDOptions): Plugin => {
1512
let client: LDClient;
1613
let flags: LDFlagSet = {};
1714

1815
return {
1916
onPluginInit: async (_ctx, { onChange }) => {
20-
client = initialize(options.clientId, {
21-
anonymous: true,
22-
kind: "user",
23-
});
17+
client = initialize(
18+
clientId,
19+
{
20+
anonymous: true,
21+
kind: "user",
22+
},
23+
options
24+
);
2425

2526
return new Promise<void>((r) => {
2627
function cleanup() {
@@ -36,9 +37,9 @@ export const remoteConfig = (options: LaunchDarklyPluginOptions): Plugin => {
3637
flags = client.allFlags();
3738
r();
3839
}
40+
3941
client.on("failed", handleFailure);
4042
client.on("ready", handleReady);
41-
4243
client.on("change", (changes: LDFlagChangeset) => {
4344
for (const [flag, { current }] of Object.entries(changes)) {
4445
flags[flag] = current;

yarn.lock

+6-1
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,11 @@
19911991
"resolved" "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz"
19921992
"version" "2.11.6"
19931993

1994+
"@radix-ui/react-icons@1.2.0":
1995+
"integrity" "sha512-NqrZxn+Ig6c6MypUt84/Nab9WBFXH75T1mhEhFjPlIYaNkp113pqlo6QdK5r7zb3b7RckDAPgUQACes0aKwcFA=="
1996+
"resolved" "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.2.0.tgz"
1997+
"version" "1.2.0"
1998+
19941999
"@sinclair/typebox@^0.25.16":
19952000
"integrity" "sha512-VEB8ygeP42CFLWyAJhN5OklpxUliqdNEUcXb4xZ/CINqtYGTjL5ukluKdKzQ0iWdUxyQ7B0539PAUhHKrCNWSQ=="
19962001
"resolved" "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.23.tgz"
@@ -7796,7 +7801,7 @@
77967801
"invariant" "^2.2.4"
77977802
"tslib" "^2.0.0"
77987803

7799-
"react@^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", "react@^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.4 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17.0.0 || ^18.0.0", "react@^18.0.0", "react@^18.1.0", "react@>= 0.14.0", "react@>=16", "react@>=16.8.0", "react@>=18", "react@16.8.0 - 18", "react@18.1.0":
7804+
"react@^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", "react@^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.4 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17.0.0 || ^18.0.0", "react@^16.x || ^17.x || ^18.x", "react@^18.0.0", "react@^18.1.0", "react@>= 0.14.0", "react@>=16", "react@>=16.8.0", "react@>=18", "react@16.8.0 - 18", "react@18.1.0":
78007805
"integrity" "sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ=="
78017806
"resolved" "https://registry.npmjs.org/react/-/react-18.1.0.tgz"
78027807
"version" "18.1.0"

0 commit comments

Comments
 (0)