Skip to content

Commit 520e711

Browse files
perf: optimize analytics app imports to avoid loading entire app store (calcom#23372)
* perf: optimize analytics app imports to avoid loading entire app store - Add analytics service generation to app-store-cli build process - Generate analytics.services.generated.ts with only analytics apps (dub) - Update getAnalytics.ts to use AnalyticsServiceMap instead of full appStore - Add NEXT_PUBLIC_IS_E2E to turbo.json globalEnv for generated files - Reduces import footprint from 100+ apps to only analytics apps with AnalyticsService - Follows same pattern as calendar services optimization from PR calcom#22450 Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * Reorder cli output * fix: follow getCalendar pattern in getAnalytics and maintain alphabetical order in turbo.json - Remove unnecessary object wrapping in getAnalytics.ts to match getCalendar.ts pattern - Move NEXT_PUBLIC_IS_E2E to correct alphabetical position in turbo.json globalEnv - Address PR feedback from keithwillcode Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * chore: update yarn.lock after analytics optimization changes Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 6d1fe32 commit 520e711

5 files changed

Lines changed: 82 additions & 24 deletions

File tree

packages/app-store-cli/src/build.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,12 +378,50 @@ function generateFiles() {
378378
calendarOutput.push(...calendarServices);
379379
}
380380

381+
const analyticsOutput = [];
382+
const analyticsServices = getExportedObject(
383+
"AnalyticsServiceMap",
384+
{
385+
importConfig: {
386+
fileToBeImported: "lib/AnalyticsService.ts",
387+
importName: "default",
388+
},
389+
lazyImport: true,
390+
},
391+
(app: App) => {
392+
const hasAnalyticsService = fs.existsSync(
393+
path.join(APP_STORE_PATH, app.path, "lib/AnalyticsService.ts")
394+
);
395+
return hasAnalyticsService;
396+
}
397+
);
398+
399+
const analyticsExportLineIndex = analyticsServices.findIndex((line) =>
400+
line.startsWith("export const AnalyticsServiceMap")
401+
);
402+
if (analyticsExportLineIndex !== -1) {
403+
const exportLine = analyticsServices[analyticsExportLineIndex];
404+
const objectContent = analyticsServices.slice(analyticsExportLineIndex + 1, -1);
405+
406+
analyticsOutput.push(
407+
exportLine.replace(
408+
"export const AnalyticsServiceMap = {",
409+
"export const AnalyticsServiceMap = process.env.NEXT_PUBLIC_IS_E2E ? {} : {"
410+
),
411+
...objectContent,
412+
"};"
413+
);
414+
} else {
415+
analyticsOutput.push(...analyticsServices);
416+
}
417+
381418
const banner = `/**
382419
This file is autogenerated using the command \`yarn app-store:build --watch\`.
383420
Don't modify this file manually.
384421
**/
385422
`;
386423
const filesToGenerate: [string, string[]][] = [
424+
["analytics.services.generated.ts", analyticsOutput],
387425
["apps.metadata.generated.ts", metadataOutput],
388426
["apps.server.generated.ts", serverOutput],
389427
["apps.browser.generated.tsx", browserOutput],
Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,11 @@
11
import logger from "@calcom/lib/logger";
2-
import type { AnalyticsService, AnalyticsServiceClass } from "@calcom/types/AnalyticsService";
2+
import type { AnalyticsService } from "@calcom/types/AnalyticsService";
33
import type { CredentialPayload } from "@calcom/types/Credential";
44

5-
import appStore from "..";
5+
import { AnalyticsServiceMap } from "../analytics.services.generated";
66

77
const log = logger.getSubLogger({ prefix: ["AnalyticsManager"] });
88

9-
interface AnalyticsApp {
10-
lib: {
11-
AnalyticsService: AnalyticsServiceClass;
12-
};
13-
}
14-
15-
const isAnalyticsService = (x: unknown): x is AnalyticsApp =>
16-
!!x &&
17-
typeof x === "object" &&
18-
"lib" in x &&
19-
typeof x.lib === "object" &&
20-
!!x.lib &&
21-
"AnalyticsService" in x.lib;
22-
239
export const getAnalyticsService = async ({
2410
credential,
2511
}: {
@@ -30,22 +16,21 @@ export const getAnalyticsService = async ({
3016

3117
const analyticsName = analyticsType.split("_")[0];
3218

33-
const analyticsAppImportFn = appStore[analyticsName as keyof typeof appStore];
19+
const analyticsAppImportFn = AnalyticsServiceMap[analyticsName as keyof typeof AnalyticsServiceMap];
3420

3521
if (!analyticsAppImportFn) {
3622
log.warn(`analytics app not implemented`);
3723
return null;
3824
}
3925

40-
const analyticsApp = await analyticsAppImportFn();
26+
const analyticsApp = await analyticsAppImportFn;
4127

42-
if (!isAnalyticsService(analyticsApp)) {
43-
log.warn(`Analytics is not implemented`);
28+
const AnalyticsService = analyticsApp.default;
29+
30+
if (!AnalyticsService || typeof AnalyticsService !== "function") {
31+
log.warn(`analytics of type ${analyticsType} is not implemented`);
4432
return null;
4533
}
4634

47-
const AnalyticsService = analyticsApp.lib.AnalyticsService;
48-
log.info("Got analyticsApp", AnalyticsService);
49-
5035
return new AnalyticsService(credential);
5136
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
This file is autogenerated using the command `yarn app-store:build --watch`.
3+
Don't modify this file manually.
4+
**/
5+
export const AnalyticsServiceMap = process.env.NEXT_PUBLIC_IS_E2E
6+
? {}
7+
: {
8+
dub: import("./dub/lib/AnalyticsService"),
9+
};

turbo.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@
8585
"HUBSPOT_CLIENT_SECRET",
8686
"IFFY_API_KEY",
8787
"INTEGRATION_TEST_MODE",
88-
"IS_E2E",
8988
"INTERCOM_SECRET",
9089
"INTERCOM_SECRET",
9190
"INSIGHTS_DATABASE_URL",
@@ -108,6 +107,7 @@
108107
"NEXT_PUBLIC_FORMBRICKS_HOST_URL",
109108
"NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID",
110109
"NEXT_PUBLIC_HOSTED_CAL_FEATURES",
110+
"NEXT_PUBLIC_IS_E2E",
111111
"NEXT_PUBLIC_MINUTES_TO_BOOK",
112112
"NEXT_PUBLIC_ORG_SELF_SERVE_ENABLED",
113113
"NEXT_PUBLIC_SENDER_ID",

yarn.lock

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3066,6 +3066,32 @@ __metadata:
30663066
languageName: unknown
30673067
linkType: soft
30683068

3069+
"@calcom/exchange2013calendar@workspace:packages/app-store/exchange2013calendar":
3070+
version: 0.0.0-use.local
3071+
resolution: "@calcom/exchange2013calendar@workspace:packages/app-store/exchange2013calendar"
3072+
dependencies:
3073+
"@calcom/lib": "*"
3074+
"@calcom/prisma": "*"
3075+
"@calcom/types": "*"
3076+
"@calcom/ui": "*"
3077+
ews-javascript-api: ^0.11.0
3078+
react-hook-form: ^7.43.3
3079+
languageName: unknown
3080+
linkType: soft
3081+
3082+
"@calcom/exchange2016calendar@workspace:packages/app-store/exchange2016calendar":
3083+
version: 0.0.0-use.local
3084+
resolution: "@calcom/exchange2016calendar@workspace:packages/app-store/exchange2016calendar"
3085+
dependencies:
3086+
"@calcom/lib": "*"
3087+
"@calcom/prisma": "*"
3088+
"@calcom/types": "*"
3089+
"@calcom/ui": "*"
3090+
ews-javascript-api: ^0.11.0
3091+
react-hook-form: ^7.43.3
3092+
languageName: unknown
3093+
linkType: soft
3094+
30693095
"@calcom/exchangecalendar@workspace:packages/app-store/exchangecalendar":
30703096
version: 0.0.0-use.local
30713097
resolution: "@calcom/exchangecalendar@workspace:packages/app-store/exchangecalendar"

0 commit comments

Comments
 (0)