# Monorepo

The gen2 SDKs, along with gen1 React SDK, are part of the same monorepo. The monorepo is configured using yarn v3 workspaces and [Nx](https://nx.app/).

The root of the yarn monorepo is the same as the github repo and called `@builder.io/root`. It is made up of the following:

- `package/sdks`: the gen2 SDKs, along with all of their integration tests
- `packages/react`: the gen1 React SDK
- `packages/core`: the gen1 core SDK, used by gen1 React SDK.
- `packages/react-tests`: the gen1 React SDK integration tests
- `packages/sdks-tests`: the integration test specs & playwright configuration for both gen1 and gen2 SDKs.

**NOTE:** Even though the monorepo root is the same root as the entire repo, not every sub-folder is part of the monorepo. Only the ones listed above are.

## Nx

Nx is a tool that handles the complexity of building your monorepo when there are a ton of inter-dependencies. By calling `yarn g:nx build` (instead of `yarn build`), Nx will run all pre-requisite steps so that your `build` command is up-to-date. This vastly simplifies local development & testing.

It will also cache the results of each step, so that if you run `yarn g:nx build` again, it will only run the steps that have changed.

# Gen2 SDKs

## Architecture

Within the gen2 SDKs folder, you will find the following:

- `package/sdks/src`: the source code for the gen2 SDKs, written in Mitosis.
- `package/sdks/output`: the source code for each of the gen2 SDKs, generated by Mitosis.
- `package/sdks/e2e`: the servers that run integration tests for each of the gen2 SDKs.

## Build process

Here is the overall picture of what happens during the gen2 SDKs build process:

- Because gen2 SDKs depend on Mitosis, which has a dependency on the gen1 React SDK, we actually need to build the `@builder.io/sdk` (core) & `@builder.io/react` (react gen1) first before we can run the mitosis build.
- We then run the mitosis build, which generates the gen2 SDKs source code in each of the `package/sdks/output` folders.
- Each individual gen2 SDK is then built using its own build tooling (some use Vite/Rollup, other require more specialized libraries specific to the intended framework).
- Finally, the integration tests are built and run. Those depend on the SDKs being built first, and also the integration tests (which live under `package/sdks-tests`).

You can visualize all of these relationships by using the Nx graph feature: run `yarn g:nx graph` anywhere in the mono-repo to launch the graph viewer.

### SDKs multi bundles

Because certain SDK code is environment-specific (specially the `evaluator` that runs arbitrary JS code), we need to generate 3 bundles for each SDK: for the browser, NodeJS and edge runtimes. This is why each SDK is built 3 times (once for each environment). Typically, the generated output will live in `lib/edge`, `lib/node` and `lib/browser` inside of each `outputs` SDK folder.

## Mitosis

Here is some general information around how Mitosis generates the gen2 SDKs source code:

- `packages/sdks/mitosis.config.js`: this file has all of the configuration for the Mitosis build. We use the Mitosis plugin system to write a lot of plugins, most of them specific to one (or more) outputs, so that the Mitosis content is modified/updated to generate exactly what we want. If you are unsure why something is changing in the generated code, this is the first place to look.
- `packages/sdks/overrides`: this folder contains the overrides for each of the gen2 SDKs. This is a last-resort for when we need a file to be completely different for a specific SDK. It is a very brittle approach, because if the original file changes, we need to manually update the override to match it exactly (same exports with same names, same function arguments, etc.). It is safer to modify files using Mitosis plugins.
- `useMetadata()`: this function is used in Mitosis components to pass configuration, either to the internal Mitosis codebase, or the Mitosis plugins in `mitosis.config.js`.

NOTE: The mitosis plugins in `mitosis.config.js` only run against mitosis component files (`.lite.tsx`), not against any `.ts` files. The latter are copied as-is to the `outputs` folder.

## SDK source code

- `src/blocks`: all the Builder blocks (Text, Image, Columns, etc.)
- `src/components`: all the Builder components used to render the SDK code.

### SDK component generation:

- `ContentVariants` handles A/B testing, and calls `Content` for each variant.
- `Content` calls `Blocks` to render the list of blocks, wrapped in `EnableEditor` to enable visual editing.
- `Blocks' calls `Block` for each block.

The logic to actually render a block is spread out over many sub-components. This is to work around multiple limitations, primarily in Svelte and React RSCs:

- `RepeatedBlock`: used by `Block` if we are dealing with a list of repeated items.
- `BlockWrapper`: renders the wrapper HTML element around the block, if there is one.
- `ComponentRef`: renders the actual block component.
  - `InteractiveElement`: if `componentRef` points to an interactive (non-RSC) component, then this wrapper is called by `ComponentRef`
