Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,120 @@ The minification of associated functions is also another major difference. Funct
A number of classes are present in the SDKs that cannot be removed without a major version. In order to reduce the size of these classes we have added support for minification of any member that starts with an underscore.

Another thing to remember is that the private and readonly only really affect TypeScript. Using JavaScript you can still access and mutate. Our minification of private members starting with an underscore also helps prevent unintentional usage from JavaScript.

## Repo Organization

The below diagram shows the dependency relationships between the various packages in the LaunchDarkly JavaScript SDKs monorepo.

Packages on the left are shared packages that should be technology agnostic. As you progress to the right, packages are more specific to a technology or implementation.

```mermaid
flowchart LR
%% Shared packages
common[shared/common]
sdk-client[shared/sdk-client]
sdk-server[shared/sdk-server]
sdk-server-edge[shared/sdk-server-edge]
akamai-edgeworker[shared/akamai-edgeworker-sdk]

%% SDK packages
server-node[sdk/server-node]
cloudflare[sdk/cloudflare]
fastly[sdk/fastly]
react-native[sdk/react-native]
browser[sdk/browser]
vercel[sdk/vercel]
akamai-base[sdk/akamai-base]
akamai-edgekv[sdk/akamai-edgekv]
server-ai[sdk/server-ai]
react-universal[sdk/react-universal]
svelte[sdk/svelte]

%% Store packages
redis[store/node-server-sdk-redis]
dynamodb[store/node-server-sdk-dynamodb]

%% Telemetry packages
node-otel[telemetry/node-server-sdk-otel]
browser-telemetry[telemetry/browser-telemetry]

%% Tooling packages
jest[tooling/jest]

%% Dependencies between shared packages
common --> sdk-client
common --> sdk-server
common --> sdk-server-edge
common --> akamai-edgeworker
sdk-server --> sdk-server-edge

%% Dependencies for SDK packages
sdk-client --> browser
sdk-client --> react-native
sdk-client --> react-universal
sdk-client --> svelte

sdk-server --> server-node
sdk-server --> server-ai

sdk-server-edge --> cloudflare
sdk-server-edge --> fastly
sdk-server-edge --> vercel

akamai-edgeworker --> akamai-base
akamai-edgeworker --> akamai-edgekv

%% Dependencies for store packages
sdk-server --> redis
sdk-server --> dynamodb

%% Dependencies for telemetry packages
server-node --> node-otel
browser --> browser-telemetry

%% Dependencies for tooling packages
react-native -.-> jest

class common,sdk-client,sdk-server,sdk-server-edge,akamai-edgeworker shared
class server-node,cloudflare,fastly,react-native,browser,vercel,akamai-base,akamai-edgekv,server-ai,react-universal,svelte sdk
class redis,dynamodb store
class node-otel,browser-telemetry telemetry
class jest tooling
```

There are a number of categories of packages in the monorepo:

1. **Shared packages** (pink): Common code shared across multiple SDKs
- `shared/common`:Common code which is intended for use by any SDK type.
- `shared/sdk-client`: Common code for client-side SDKs.
- `shared/sdk-server`: Common code for server-side SDKs
- `shared/sdk-server-edge`: Common code for edge SDKs
- `shared/akamai-edgeworker-sdk`: Common code for Akamai edge worker SDKs

2. **SDK packages** (blue): Actual SDK implementations for different platforms
- Browser, React Native, Server Node, Cloudflare, Fastly, Vercel, Akamai, etc.

3. **Store packages** (green): Persistent storage implementations
- Redis and DynamoDB implementations

4. **Telemetry packages** (purple): Monitoring and telemetry integrations
- OpenTelemetry for Node.js and browser telemetry

5. **Tooling packages** (red): Development and testing tools
- Jest testing utilities

### Depenencies

In general dependencies should be avoided unless they are absolutely necessary. For each dependency several considerations should be made:

- Size: Each dependency will increase the final bundle size. This is important for the browser SDK where bundle size impacts load time and costs.
- Maintenance: Dependencies can become unmaintained or deprecated over time. This requires that we routinely check dependencies and find replacements if they have become unmaintained.
- Security: Dependencies can have a large surface area of security vulnerabilities. It is rare we would fully utlize a dependency, and as such vulnerabilities often do not apply, but we still need to patch and provide updates.
- Compatibility: Each dependency will need to be compatible with the supported platforms it impacts. At any given point it isn't certain the potential platforms that could be impacted over time. For instance something may work in every current edge environment, but may not be compatible with a future edge environment.
- Conflicts: Dependencies can introduce conflicts with other dependencies in application code.

We only want to use dependencies for functionality with highly-specified behavior, which are widely used, maintained, and have a large community.

It is most important to avoid dependencies in the common package, sdk-client, and sdk-server packages.

Individual SDK packages have a known execution environment and vetting a dependency is less complex, and some SDKs have specific platform dependencies that must be included. For example the edge SDKs must use their provider's edge store, and may require dependencies to do so.