From 5a87db5fe9e5022fd767c990ec40304f29152da1 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Wed, 4 Sep 2024 16:04:17 +0200 Subject: [PATCH] feature: add preliminary support for dom components (#75) * feature: add `dom` environment based on `web` + `customTransformOptions.dom` existence * feature: add basic `dom` environment ui * refactor(ui): replace globe with panel-top to emphasize "embedded webview" --- .../expo-atlas-ui/components/BundleTag.tsx | 4 ++ .../components/EnvironmentIcon.tsx | 1 + .../components/EnvironmentName.tsx | 1 + .../expo-atlas/src/data/MetroGraphSource.ts | 45 +++++++++++++++++-- packages/expo-atlas/src/data/types.ts | 2 +- 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/packages/expo-atlas-ui/components/BundleTag.tsx b/packages/expo-atlas-ui/components/BundleTag.tsx index 6167c45..3dfe8b4 100644 --- a/packages/expo-atlas-ui/components/BundleTag.tsx +++ b/packages/expo-atlas-ui/components/BundleTag.tsx @@ -18,6 +18,7 @@ const bundleTagVariants = cva('', { } satisfies Record, environment: { client: '', + dom: 'bg-palette-blue3', node: 'bg-palette-orange3', 'react-server': 'bg-palette-orange3', } satisfies Record, @@ -72,6 +73,9 @@ export function BundleTag({ className, platform, environment, ...props }: Bundel Client — Bundles that run on device. +
  • + DOM — Webview embedded components. +
  • SSR — Bundles that only run on server. diff --git a/packages/expo-atlas-ui/components/EnvironmentIcon.tsx b/packages/expo-atlas-ui/components/EnvironmentIcon.tsx index d67da9b..de09989 100644 --- a/packages/expo-atlas-ui/components/EnvironmentIcon.tsx +++ b/packages/expo-atlas-ui/components/EnvironmentIcon.tsx @@ -10,6 +10,7 @@ type EnvironmentIconProps = Omit< const iconsByEnvironment: Record = { client: require('lucide-react/dist/esm/icons/tablet-smartphone').default, + dom: require('lucide-react/dist/esm/icons/panel-top').default, node: require('lucide-react/dist/esm/icons/hexagon').default, 'react-server': require('lucide-react/dist/esm/icons/server').default, }; diff --git a/packages/expo-atlas-ui/components/EnvironmentName.tsx b/packages/expo-atlas-ui/components/EnvironmentName.tsx index dba8b51..09cc6b0 100644 --- a/packages/expo-atlas-ui/components/EnvironmentName.tsx +++ b/packages/expo-atlas-ui/components/EnvironmentName.tsx @@ -8,6 +8,7 @@ type EnvironmentNameProps = PropsWithChildren<{ export const environmentNames: Record = { client: 'Client', + dom: 'DOM', node: 'SSR', 'react-server': 'RSC', }; diff --git a/packages/expo-atlas/src/data/MetroGraphSource.ts b/packages/expo-atlas/src/data/MetroGraphSource.ts index de7392c..6a991fa 100644 --- a/packages/expo-atlas/src/data/MetroGraphSource.ts +++ b/packages/expo-atlas/src/data/MetroGraphSource.ts @@ -107,16 +107,17 @@ export function convertGraph(options: ConvertGraphToAtlasOptions): AtlasBundle { const environment = getEnvironment(options) ?? 'client'; const serializeOptions = convertSerializeOptions(options); const transformOptions = convertTransformOptions(options); + const entryPoint = getEntryPoint(options, environment); return { - id: Buffer.from( - `${path.relative(sharedRoot, options.entryPoint)}+${platform}+${environment}` - ).toString('base64url'), + id: Buffer.from(`${path.relative(sharedRoot, entryPoint)}+${platform}+${environment}`).toString( + 'base64url' + ), platform, environment, projectRoot: options.projectRoot, sharedRoot, - entryPoint: options.entryPoint, + entryPoint, runtimeModules: options.preModules.map((module) => convertModule(options, module, sharedRoot)), modules: collectEntryPointModules(options, sharedRoot), serializeOptions, @@ -253,6 +254,15 @@ function moduleIsVirtual(module: MetroModule) { function getEnvironment(options: Pick) { const environment = options.graph.transformOptions?.customTransformOptions?.environment; + // Check if this graph is related to a DOM component + // NOTE(cedric): this is early/alpha support and may change in the future + if ( + options.graph.transformOptions.platform === 'web' && + !!options.graph.transformOptions.customTransformOptions?.dom + ) { + return 'dom' as AtlasBundle['environment']; + } + if (typeof environment === 'string') { return environment as AtlasBundle['environment']; } @@ -270,3 +280,30 @@ function getPlatform(options: Pick) { return null; } + +/** + * Determine if this graph is related to a DOM component, using the (custom) transform options. + * @remarks - This is preliminary support, and may change in the future + */ +function getEntryPoint( + options: ConvertGraphToAtlasOptions, + environment: AtlasBundle['environment'] = 'client' +) { + if (environment === 'dom') { + console.log({ + entryPoint: options.entryPoint, + dom: options.graph.transformOptions.customTransformOptions?.dom, + _result: path.join( + options.entryPoint, + options.graph.transformOptions.customTransformOptions!.dom as string + ), + }); + } + + return environment !== 'dom' + ? options.entryPoint + : path.join( + options.entryPoint, + options.graph.transformOptions.customTransformOptions!.dom as string + ); +} diff --git a/packages/expo-atlas/src/data/types.ts b/packages/expo-atlas/src/data/types.ts index 6e46f24..746ff99 100644 --- a/packages/expo-atlas/src/data/types.ts +++ b/packages/expo-atlas/src/data/types.ts @@ -21,7 +21,7 @@ export type AtlasBundle = { /** The platform for which the bundle was created */ platform: 'android' | 'ios' | 'web' | 'unknown'; /** The environment this bundle is compiled for */ - environment: 'client' | 'node' | 'react-server'; + environment: 'client' | 'dom' | 'node' | 'react-server'; /** The absolute path to the root of the project */ projectRoot: string; /** The absolute path to the shared root of all imported modules */