Skip to content

Commit 1f8b8fa

Browse files
authored
ENG-1785: Cache getAllDiscourseNodes (#1067)
* Cache discourse node type reads * Extract feature flag keys into FEATURE_FLAG_KEYS const Replaces repeated "Use new settings store" string literals in accessors.ts with a typed FEATURE_FLAG_KEYS constant, following the existing *_KEYS convention in settingKeys.ts. Makes typos a compile error.
1 parent 04817c2 commit 1f8b8fa

6 files changed

Lines changed: 63 additions & 6 deletions

File tree

apps/roam/src/components/settings/DiscourseNodeConfigPanel.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import setBlockProps from "~/utils/setBlockProps";
2222
import { DiscourseNodeSchema } from "./utils/zodSchema";
2323
import { getGlobalSettings, setGlobalSetting } from "./utils/accessors";
2424
import { GLOBAL_KEYS } from "./utils/settingKeys";
25+
import { invalidateDiscourseNodeTypeCaches } from "~/utils/discourseNodeTypeCache";
2526

2627
type DiscourseNodeConfigPanelProps = React.ComponentProps<
2728
CustomField["options"]["component"]
@@ -60,6 +61,7 @@ const DiscourseNodeConfigPanel: React.FC<DiscourseNodeConfigPanelProps> = ({
6061
await window.roamAlphaAPI.deletePage({
6162
page: { uid },
6263
});
64+
invalidateDiscourseNodeTypeCaches();
6365
setNodes((prevNodes) => prevNodes.filter((nn) => nn.type !== uid));
6466
refreshConfigTree();
6567
setDeleteConfirmation(null);
@@ -117,6 +119,7 @@ const DiscourseNodeConfigPanel: React.FC<DiscourseNodeConfigPanelProps> = ({
117119
format,
118120
}),
119121
);
122+
invalidateDiscourseNodeTypeCaches();
120123
setNodes([
121124
...nodes,
122125
{

apps/roam/src/components/settings/utils/accessors.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ import {
2424
} from "~/utils/getExportSettings";
2525
import { getSuggestiveModeConfigAndUids } from "~/utils/getSuggestiveModeConfigSettings";
2626
import { getLeftSidebarSettings } from "~/utils/getLeftSidebarSettings";
27+
import {
28+
getDiscourseNodeTypeCacheVersion,
29+
invalidateDiscourseNodeTypeCaches,
30+
} from "~/utils/discourseNodeTypeCache";
2731

2832
import {
2933
DG_BLOCK_PROP_SETTINGS_PAGE_TITLE,
@@ -40,7 +44,12 @@ import {
4044
type DiscourseNodeSettings,
4145
type Condition as SchemaCondition,
4246
} from "./zodSchema";
43-
import { PERSONAL_KEYS, QUERY_KEYS, GLOBAL_KEYS } from "./settingKeys";
47+
import {
48+
FEATURE_FLAG_KEYS,
49+
PERSONAL_KEYS,
50+
QUERY_KEYS,
51+
GLOBAL_KEYS,
52+
} from "./settingKeys";
4453

4554
const isRecord = (value: unknown): value is Record<string, unknown> =>
4655
typeof value === "object" && value !== null && !Array.isArray(value);
@@ -716,15 +725,15 @@ export const getFeatureFlag = (key: keyof FeatureFlags): boolean => {
716725
};
717726

718727
export const isNewSettingsStoreEnabled = (): boolean => {
719-
return getFeatureFlag("Use new settings store");
728+
return getFeatureFlag(FEATURE_FLAG_KEYS.useNewSettingsStore);
720729
};
721730

722731
export const readAllLegacyFeatureFlags = (): Partial<FeatureFlags> => {
723732
const flags: Partial<FeatureFlags> = {};
724733
for (const [key, reader] of Object.entries(FEATURE_FLAG_LEGACY_MAP)) {
725734
flags[key as keyof FeatureFlags] = reader();
726735
}
727-
flags["Use new settings store"] = false;
736+
flags[FEATURE_FLAG_KEYS.useNewSettingsStore] = false;
728737
return flags;
729738
};
730739

@@ -767,6 +776,10 @@ export const setFeatureFlag = (
767776
keys: [STATIC_TOP_LEVEL_ENTRIES.featureFlags.key, key],
768777
value: validatedValue,
769778
});
779+
780+
if (key === FEATURE_FLAG_KEYS.useNewSettingsStore) {
781+
invalidateDiscourseNodeTypeCaches();
782+
}
770783
};
771784

772785
export const getGlobalSettings = (): GlobalSettings => {
@@ -880,7 +893,7 @@ export const bulkReadSettings = (): SettingsSnapshot => {
880893

881894
const featureFlags = FeatureFlagsSchema.parse(featureFlagsProps || {});
882895

883-
if (!featureFlags["Use new settings store"]) {
896+
if (!featureFlags[FEATURE_FLAG_KEYS.useNewSettingsStore]) {
884897
return {
885898
featureFlags,
886899
globalSettings: readAllLegacyGlobalSettings() as GlobalSettings,
@@ -967,7 +980,7 @@ export const getDiscourseNodeSetting = <T = unknown>(
967980
nodeType: string,
968981
keys: string[],
969982
): T | undefined => {
970-
if (!bulkReadSettings().featureFlags["Use new settings store"]) {
983+
if (!bulkReadSettings().featureFlags[FEATURE_FLAG_KEYS.useNewSettingsStore]) {
971984
return getLegacyDiscourseNodeSetting(nodeType, keys) as T | undefined;
972985
}
973986

@@ -1023,6 +1036,7 @@ export const setDiscourseNodeSetting = (
10231036
}
10241037

10251038
setBlockPropAtPath(pageUid, keys, value);
1039+
invalidateDiscourseNodeTypeCaches();
10261040
};
10271041

10281042
const addConditionUids = (conditions: SchemaCondition[]): Condition[] =>
@@ -1131,7 +1145,17 @@ const migrateNodeBlockProps = (
11311145
return migrated;
11321146
};
11331147

1148+
let allDiscourseNodesCache: {
1149+
version: number;
1150+
nodes: DiscourseNode[];
1151+
} | null = null;
1152+
11341153
export const getAllDiscourseNodes = (): DiscourseNode[] => {
1154+
const cacheVersion = getDiscourseNodeTypeCacheVersion();
1155+
if (allDiscourseNodesCache?.version === cacheVersion) {
1156+
return allDiscourseNodesCache.nodes;
1157+
}
1158+
11351159
const results = window.roamAlphaAPI.data.fast.q(`
11361160
[:find ?uid ?title (pull ?page [:block/props])
11371161
:where
@@ -1191,5 +1215,6 @@ export const getAllDiscourseNodes = (): DiscourseNode[] => {
11911215
}
11921216
}
11931217

1218+
allDiscourseNodesCache = { version: cacheVersion, nodes };
11941219
return nodes;
11951220
};

apps/roam/src/components/settings/utils/migrateLegacyToBlockProps.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
getPersonalSettingsKey,
2424
} from "./zodSchema";
2525
import type { z } from "zod";
26+
import { invalidateDiscourseNodeTypeCaches } from "~/utils/discourseNodeTypeCache";
2627

2728
const LOG_PREFIX = "[DG BlockProps Migration]";
2829
const GRAPH_MIGRATION_MARKER = "Block props migrated";
@@ -63,11 +64,13 @@ const migrateSection = ({
6364
blockUid,
6465
schema,
6566
legacyData,
67+
onWrite,
6668
}: {
6769
label: string;
6870
blockUid: string;
6971
schema: z.ZodTypeAny;
7072
legacyData: Record<string, unknown>;
73+
onWrite?: () => void;
7174
}): boolean => {
7275
const currentProps = getBlockProps(blockUid);
7376

@@ -103,6 +106,7 @@ const migrateSection = ({
103106
}
104107

105108
setBlockProps(blockUid, parsedLegacy, false);
109+
onWrite?.();
106110
console.log(`${LOG_PREFIX} ${label}: migrated`);
107111
return true;
108112
};
@@ -156,6 +160,7 @@ const migrateDiscourseNodes = async (): Promise<boolean> => {
156160
blockUid: nodePageUid,
157161
schema: DiscourseNodeSchema,
158162
legacyData,
163+
onWrite: invalidateDiscourseNodeTypeCaches,
159164
})
160165
) {
161166
allOk = false;

apps/roam/src/components/settings/utils/settingKeys.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type {
2+
FeatureFlags,
23
PersonalSettings,
34
QuerySettings,
45
GlobalSettings,
@@ -10,6 +11,13 @@ import type {
1011
SuggestiveRules,
1112
} from "./zodSchema";
1213

14+
export const FEATURE_FLAG_KEYS = {
15+
enableLeftSidebar: "Enable left sidebar",
16+
duplicateNodeAlertEnabled: "Duplicate node alert enabled",
17+
suggestiveModeOverlayEnabled: "Suggestive mode overlay enabled",
18+
useNewSettingsStore: "Use new settings store",
19+
} as const satisfies Record<string, keyof FeatureFlags>;
20+
1321
export const PERSONAL_KEYS = {
1422
discourseContextOverlay: "Discourse context overlay",
1523
textSelectionPopup: "Text selection popup",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
let discourseNodeTypeCacheVersion = 0;
2+
3+
export const invalidateDiscourseNodeTypeCaches = (): void => {
4+
discourseNodeTypeCacheVersion += 1;
5+
};
6+
7+
export const getDiscourseNodeTypeCacheVersion = (): number =>
8+
discourseNodeTypeCacheVersion;

apps/roam/src/utils/findDiscourseNode.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import getDiscourseNodes, { type DiscourseNode } from "./getDiscourseNodes";
22
import matchDiscourseNode from "./matchDiscourseNode";
33
import type { SettingsSnapshot } from "~/components/settings/utils/accessors";
4+
import { getDiscourseNodeTypeCacheVersion } from "./discourseNodeTypeCache";
45

5-
const discourseNodeTypeCache: Record<string, DiscourseNode | false> = {};
6+
let discourseNodeTypeCache: Record<string, DiscourseNode | false> = {};
7+
let discourseNodeTypeCacheVersion = -1;
68

79
const findDiscourseNode = ({
810
uid,
@@ -15,6 +17,12 @@ const findDiscourseNode = ({
1517
nodes?: DiscourseNode[];
1618
snapshot?: SettingsSnapshot;
1719
}): DiscourseNode | false => {
20+
const currentCacheVersion = getDiscourseNodeTypeCacheVersion();
21+
if (discourseNodeTypeCacheVersion !== currentCacheVersion) {
22+
discourseNodeTypeCache = {};
23+
discourseNodeTypeCacheVersion = currentCacheVersion;
24+
}
25+
1826
if (typeof discourseNodeTypeCache[uid] !== "undefined") {
1927
return discourseNodeTypeCache[uid];
2028
}

0 commit comments

Comments
 (0)