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

feature: add environment to partial bundles and render ssr/rsc in bundle selector #66

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
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
18 changes: 12 additions & 6 deletions src/data/AtlasFileSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,23 @@ export class AtlasFileSource implements AtlasSource {
* This only reads the bundle name, and adds a line number as ID.
*/
export async function listAtlasEntries(filePath: string) {
const bundlePattern = /^\["([^"]+)","([^"]+)","([^"]+)","([^"]+)"/;
const bundlePattern = /^\["([^"]+)","([^"]+)","([^"]+)","([^"]+)","([^"]+)"/;
const entries: PartialAtlasBundle[] = [];

await forEachJsonLines(filePath, (contents, line) => {
// Skip the metadata line
if (line === 1) return;

const [_, platform, projectRoot, sharedRoot, entryPoint] = contents.match(bundlePattern) ?? [];
const [_, platform, projectRoot, sharedRoot, entryPoint, environment] =
contents.match(bundlePattern) ?? [];
if (platform && projectRoot && sharedRoot && entryPoint) {
entries.push({
id: String(line),
platform: platform as any,
projectRoot,
sharedRoot,
entryPoint,
environment: environment as any,
});
}
});
Expand All @@ -72,10 +74,11 @@ export async function readAtlasEntry(filePath: string, id: number): Promise<Atla
projectRoot: atlasEntry[1],
sharedRoot: atlasEntry[2],
entryPoint: atlasEntry[3],
runtimeModules: atlasEntry[4],
modules: new Map(atlasEntry[5].map((module: AtlasModule) => [module.absolutePath, module])),
transformOptions: atlasEntry[6],
serializeOptions: atlasEntry[7],
environment: atlasEntry[4],
runtimeModules: atlasEntry[5],
modules: new Map(atlasEntry[6].map((module: AtlasModule) => [module.absolutePath, module])),
transformOptions: atlasEntry[7],
serializeOptions: atlasEntry[8],
};
}

Expand All @@ -98,10 +101,13 @@ export function waitUntilAtlasFileReady() {
*/
export function writeAtlasEntry(filePath: string, entry: AtlasBundle) {
const line = [
// These must all be strings
entry.platform,
entry.projectRoot,
entry.sharedRoot,
entry.entryPoint,
entry.transformOptions?.customTransformOptions.environment ?? 'client',
// These can be more complex types
entry.runtimeModules,
Array.from(entry.modules.values()),
entry.transformOptions,
Expand Down
9 changes: 3 additions & 6 deletions src/data/MetroGraphSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export class MetroGraphSource implements AtlasSource {
projectRoot: bundle.projectRoot,
sharedRoot: bundle.sharedRoot,
entryPoint: bundle.entryPoint,
environment: bundle.environment,
}));
}

Expand Down Expand Up @@ -104,11 +105,7 @@ export function convertGraph(options: ConvertGraphToAtlasOptions): AtlasBundle {
const sharedRoot = getSharedRoot(options);
const serializeOptions = convertSerializeOptions(options);
const transformOptions = convertTransformOptions(options);
const platform =
transformOptions?.customTransformOptions?.environment === 'node'
? 'server'
: transformOptions?.platform ?? 'unknown';

const platform = transformOptions?.platform ?? 'unknown';
return {
id: Buffer.from(`${path.relative(sharedRoot, options.entryPoint)}+${platform}`).toString(
'base64url'
Expand All @@ -120,7 +117,7 @@ export function convertGraph(options: ConvertGraphToAtlasOptions): AtlasBundle {
runtimeModules: options.preModules.map((module) => convertModule(options, module, sharedRoot)),
modules: collectEntryPointModules(options, sharedRoot),
serializeOptions,
transformOptions,
environment: transformOptions?.customTransformOptions?.environment ?? 'client',
};
}

Expand Down
6 changes: 4 additions & 2 deletions src/data/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ export interface AtlasSource {

export type PartialAtlasBundle = Pick<
AtlasBundle,
'id' | 'platform' | 'projectRoot' | 'sharedRoot' | 'entryPoint'
'id' | 'platform' | 'projectRoot' | 'sharedRoot' | 'entryPoint' | 'environment'
>;

export type AtlasBundle = {
/** The unique reference or ID to this entry */
id: string;
/** The platform for which the bundle was created */
platform: 'android' | 'ios' | 'web' | 'server';
platform: 'android' | 'ios' | 'web';
/** Target bundling environment */
environment: 'client' | '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 */
Expand Down
1 change: 1 addition & 0 deletions webui/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EXPO_USE_FAST_RESOLVER=1
2 changes: 1 addition & 1 deletion webui/src/app/(atlas)/[bundle].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function BundlePage() {
<LayoutTitle>
<h1 className="text-lg font-bold mr-8">Bundle</h1>
<PropertySummary>
<Tag variant={bundle.platform} />
<Tag variant={bundle.platform} environment={bundle.environment} />
{!!modules.data && <span>{modules.data.bundle.moduleFiles} modules</span>}
{!!modules.data && <span>{formatFileSize(modules.data.bundle.moduleSize)}</span>}
{!!modules.data && modulesAreFiltered && (
Expand Down
2 changes: 1 addition & 1 deletion webui/src/app/(atlas)/[bundle]/folders/[path].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function FolderPage() {
<LayoutTitle>
<BreadcrumbLinks bundle={bundle} path={relativePath!} />
<PropertySummary>
<Tag variant={bundle.platform} />
<Tag variant={bundle.platform} environment={bundle.environment} />
<span>folder</span>
{!!modules.data?.filtered.moduleFiles && (
<span>
Expand Down
2 changes: 1 addition & 1 deletion webui/src/app/(atlas)/[bundle]/modules/[path].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function ModulePage() {
<LayoutTitle>
<BreadcrumbLinks bundle={bundle} path={relativePath!} />
<PropertySummary>
<Tag variant={bundle.platform} />
<Tag variant={bundle.platform} environment={bundle.environment} />
{!!module.data?.package && <span>{module.data.package}</span>}
{!!module.data && <span>{getModuleType(module.data)}</span>}
{!!module.data && <span>{formatFileSize(module.data.size)}</span>}
Expand Down
8 changes: 6 additions & 2 deletions webui/src/app/--/bundles/index+api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ export async function GET() {
}

function sortBundlesByPlatform(a: PartialAtlasBundle, b: PartialAtlasBundle) {
if (a.platform === 'server') return 1;
if (b.platform === 'server') return -1;
if (isNonClient(a)) return 1;
if (isNonClient(b)) return -1;
return 0;
}

function isNonClient(a: PartialAtlasBundle) {
return a.environment && a.environment !== 'client';
}
14 changes: 12 additions & 2 deletions webui/src/components/BundleSelectForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ export function BundleSelectForm() {
<Select.Root value={bundle.id} onValueChange={(bundle) => router.setParams({ bundle })}>
<Select.Trigger asChild>
<Button variant="quaternary" size="sm">
<Tag variant={bundle.platform} size="xs" className="mr-2" />
<Tag
variant={bundle.platform}
environment={bundle.environment}
size="xs"
className="mr-2"
/>
<Select.Value placeholder="Select bundle to inspect" />
<Select.Icon className="text-icon-default">
<ChevronDownIcon size={16} className="m-1 mr-0 align-middle" />
Expand All @@ -39,7 +44,12 @@ export function BundleSelectForm() {
<div key={item.id}>
<Select.Item value={item.id} asChild>
<Button variant="quaternary" size="sm" className="w-full !justify-start my-0.5">
<Tag variant={item.platform} size="xs" className="mr-2" />
<Tag
variant={item.platform}
environment={item.environment}
size="xs"
className="mr-2"
/>
<Select.ItemText>{relativeBundlePath(item, item.entryPoint)}</Select.ItemText>
</Button>
</Select.Item>
Expand Down
25 changes: 20 additions & 5 deletions webui/src/ui/Tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ const tagVariants = cva(
danger: 'bg-danger text-danger',
// Platform-specific variants
web: 'bg-palette-orange3 text-palette-orange11',
server: 'bg-palette-orange3 text-palette-orange11',
ios: 'bg-palette-blue3 text-palette-blue11',
android: 'bg-palette-green3 text-palette-green11',
},
environment: {
// Platform-specific variants
node: 'bg-palette-orange3 text-palette-orange11',
client: 'bg-palette-blue3 text-palette-blue11',
'react-server': 'bg-palette-green3 text-palette-green11',
},
size: {
xs: 'px-3 py-1 text-3xs/4',
sm: 'px-4 py-1 text-xs',
Expand All @@ -32,23 +37,33 @@ const tagVariants = cva(
}
);

const platformChildren: Record<'android' | 'ios' | 'server' | 'web', string> = {
const platformChildren: Record<'android' | 'ios' | 'web', string> = {
android: 'Android',
ios: 'iOS',
server: 'Server',
web: 'Web',
};

const envChildren: Record<'client' | 'node' | 'react-server', string> = {
client: 'Client',
node: 'SSR',
'react-server': 'RSC',
};

type TagProps = ComponentProps<'span'> & VariantProps<typeof tagVariants>;

export const Tag = forwardRef<HTMLSpanElement, TagProps>(
({ className, variant, size, children, ...props }, ref) => {
({ className, variant, environment, size, children, ...props }, ref) => {
if (variant && variant in platformChildren) {
children = platformChildren[variant as keyof typeof platformChildren];
}

const isDefaultEnvironment = !environment || environment === 'client';
if (!isDefaultEnvironment) {
children += ' × ' + envChildren[environment] || environment;
}

return (
<span className={tagVariants({ variant, size, className })} ref={ref} {...props}>
<span className={tagVariants({ variant, environment, size, className })} ref={ref} {...props}>
{children}
</span>
);
Expand Down