@herp-inc/cycle-launchdarkly-driver
Version:
LaunchDarkly driver for Cycle.js, based on Standard Schema
79 lines (76 loc) • 2.86 kB
JavaScript
import * as LaunchDarkly from 'launchdarkly-js-client-sdk';
import { Stream } from 'xstream';
import delay from 'xstream/extra/delay';
function makeClient$(...[envKey, context, options]) {
let client;
return Stream.create({
start: (listener) => {
client = LaunchDarkly.initialize(envKey, context, options);
void client.waitForInitialization().then(() => {
if (client === undefined) {
return;
}
listener.next(client);
});
},
stop: () => {
void client?.close();
client = undefined;
},
});
}
/**
* A factory function for the LaunchDarkly driver.
*/
function makeLaunchDarklyDriver(params) {
const { defaultValues, envKey, fallbackDelay = 0, options } = params;
const context = 'context' in params ? params.context : params.user;
const client$ = makeClient$(envKey, context, options);
const $ = client$.map((client) => {
let onNext;
return Stream.create({
start(listener) {
onNext = () => {
const allFlags = client.allFlags();
if (params.schema === undefined) {
const result = params.decoder.decode(allFlags);
if (result._tag === 'Right') {
listener.next(result.right);
}
else {
options?.logger?.warn(`Failed to decode the flags: ${JSON.stringify(allFlags)}`);
}
}
else {
const result = params.schema['~standard'].validate(allFlags);
if (result instanceof Promise) {
throw new TypeError('Schema validation must be synchronous');
}
if (result.issues === undefined) {
listener.next(result.value);
}
else {
options?.logger?.warn(`Failed to decode the flags: ${JSON.stringify(allFlags)}`);
}
}
};
client.on('change', onNext);
onNext();
},
stop() {
client.off('change', onNext);
},
});
});
const defaultValues$ = Stream.of(defaultValues).compose(delay(fallbackDelay));
return () => ({
stream: $.startWith(defaultValues$).flatten().remember(),
});
}
/**
* A factory function to create a mocked `FeaturesSource`, for testing purposes.
*/
function makeMockFeaturesDriver($) {
return () => ({ stream: $ });
}
export { makeLaunchDarklyDriver, makeMockFeaturesDriver };