Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Fastly Edge SDK #723

Open
wants to merge 35 commits into
base: main
Choose a base branch
from

Conversation

ldhenry
Copy link
Contributor

@ldhenry ldhenry commented Jan 3, 2025

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

Describe the solution you've provided

This PR adds a new Fastly Compute SDK. This SDK must be used in conjunction with our upcoming Fastly KV integration. The SDK is essentially the same as the other edge integrations (Akamai, Cloudflare, Vercel), with the following changes:

  • node:events is not compatible with Fastly's runtime. As a result, we cannot use @launchdarkly/sdk-server-edge. Instead, I copied the contents of @launchdarkly/sdk-server-edge into the fastly package and replaced createCallbacks.ts with an empty implementation.
  • Enabled sendEvents by default.
  • Added the eventsUri option to allow for sending events to a custom endpoint.
  • Added a new optional eventsBackendName option. A Fastly Backend configured to https://events.launchdarkly.com is required for sending events. The default value is launchdarkly. This option is passed to Fastly's customized fetch().

I added an example app that demonstrates using the SDK to evaluate a feature flag edge to control the static image served.

I published an alpha version to npm here.

Copy link
Contributor

github-actions bot commented Jan 3, 2025

@launchdarkly/js-sdk-common size report
This is the brotli compressed size of the ESM build.
Size: 19014 bytes
Size limit: 21000

Copy link
Contributor

github-actions bot commented Jan 3, 2025

@launchdarkly/js-client-sdk size report
This is the brotli compressed size of the ESM build.
Size: 19871 bytes
Size limit: 21000

Copy link
Contributor

github-actions bot commented Jan 3, 2025

@launchdarkly/js-client-sdk-common size report
This is the brotli compressed size of the ESM build.
Size: 15371 bytes
Size limit: 20000

@ldhenry ldhenry marked this pull request as ready for review January 3, 2025 17:58
@ldhenry ldhenry requested a review from a team as a code owner January 3, 2025 17:58
@ldhenry ldhenry requested a review from kinyoklion January 3, 2025 17:58
@@ -0,0 +1,46 @@
import { internal } from '@launchdarkly/js-server-sdk-common';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All tests in this directory were copied over from @launchdarkly/sdk-server-edge

@@ -0,0 +1,59 @@
import { PlatformData, SdkData } from '@launchdarkly/js-server-sdk-common';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was copied from @launchdarkly/sdk-server-edge

@mmrj
Copy link
Contributor

mmrj commented Jan 3, 2025

(docs ticket is at DOCS-973 and currently scheduled for week of 1/6)

@@ -0,0 +1,116 @@
import type {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was copied from @launchdarkly/sdk-server-edge

@@ -0,0 +1,24 @@
import { Info, internal, LDClientImpl, LDOptions } from '@launchdarkly/js-server-sdk-common';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was copied from @launchdarkly/sdk-server-edge

@@ -0,0 +1,9 @@
const createCallbacks = () => ({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the new empty implementation to get around the lack of node:events

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think we can make a task, not blocking this, which removes the dependency from the common package.

That would then allow for the eventually removal of most of the code for this package.

@@ -0,0 +1,17 @@
import { BasicLogger, LDOptions } from '@launchdarkly/js-server-sdk-common';
Copy link
Contributor Author

@ldhenry ldhenry Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mostly copied from @launchdarkly/sdk-server-edge

@@ -0,0 +1,49 @@
import CryptoJS from 'crypto-js';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything in this directory was copied from @launchdarkly/sdk-server-edge

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know if we need crypto-js, or does fastly compute have its own suitable alternatives?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like they have explicitly tested crypto-js as noted here. With that being said, I'll do a test to see if we can get away without it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did some digging and it looks like Fastly exposes SimpleCrypto. I started to implement our Hasher with this but hit a roadblock because SimpleCrypto's digest function returns a promise.

I'll stick with crypto-js for now unless you are aware of a workaround.


fetch(url: string, options: Options = {}): Promise<Response> {
// @ts-ignore
return fetch(url, { ...options, backend: this.eventsBackend });
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the main differentiator between the other edge SDKs. We are required to pass a fastly-specific backend parameter.

Copy link
Member

@kinyoklion kinyoklion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not looked through everything yet, but I did do an initial pass with a few items. Sorry for the delay.

@@ -0,0 +1,9 @@
const createCallbacks = () => ({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think we can make a task, not blocking this, which removes the dependency from the common package.

That would then allow for the eventually removal of most of the code for this package.

@@ -0,0 +1,49 @@
import CryptoJS from 'crypto-js';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know if we need crypto-js, or does fastly compute have its own suitable alternatives?

@ldhenry
Copy link
Contributor Author

ldhenry commented Jan 17, 2025

I've not looked through everything yet, but I did do an initial pass with a few items. Sorry for the delay.

No problem and I appreciate your feedback. I'll take another pass next week.

const client = new LDClient('client-side-id', createBasicPlatform().info, {
sendEvents: true,
eventsBackendName: 'launchdarkly',
eventsUri: 'https://custom-base-uri.launchdarkly.com',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the option to set a custom eventsUri. baseUri doesn't really make sense for these integrations so I also added logic to set baseUri to eventsUri if eventsUri is specified in order to pass the validation in sdk-server-common.


export const defaultOptions: LDOptions = {
stream: false,
sendEvents: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike our other Edge SDKs, this will send events by default.

@ldhenry ldhenry requested a review from kinyoklion February 10, 2025 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants