Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
343dc11
ENG-1616: Bulk-read settings + thread snapshot (with timing logs)
sid597 Apr 6, 2026
4d5c720
ENG-1616: Remove plugin-load timing logs
sid597 Apr 6, 2026
b13d401
ENG-1616: Address review — typed indexing, restore dgDualReadLog, opt…
sid597 Apr 6, 2026
4140f5c
ENG-1616: Log total plugin load time
sid597 Apr 6, 2026
aea086d
ENG-1616: Tighten init-only leaves to required snapshot, AGENTS.md co…
sid597 Apr 8, 2026
076910f
ENG-1617: Single-pull settings reads + dialog snapshot threading
sid597 Apr 8, 2026
533e59d
ENG-1617: Refresh snapshot on Home tab nav + reuse readPathValue
sid597 Apr 8, 2026
09e9a25
ENG-1617: Per-tab snapshot threading via bulkReadSettings
sid597 Apr 8, 2026
3a7ab07
ENG-1617: Lift settings snapshot to SettingsDialog, thread to all tabs
sid597 Apr 10, 2026
ba70952
ENG-1617: Remove timing instrumentation, per-call dual-read, flag-awa…
sid597 Apr 10, 2026
38996b3
ENG-1617: Eliminate double bulkReadSettings calls in accessor functions
sid597 Apr 10, 2026
bcf19ec
ENG-1617: Re-read snapshot on tab change to prevent stale initialValues
sid597 Apr 10, 2026
24e521b
ENG-1616: Address review — rename snapshot vars, flag-gate bulkRead, …
sid597 Apr 10, 2026
0d85282
ENG-1617: Fix DiscourseNodeSelectPanel fallback to use first option i…
sid597 Apr 10, 2026
52ffaed
ENG-1617: Rename snapshot variables to settings for clarity
sid597 Apr 11, 2026
86a7491
Merge branch 'eng-1616-add-getconfigtree-equivalent-for-block-pros-on…
sid597 Apr 15, 2026
b15b0ab
Fix legacy bulk settings fallback
sid597 Apr 15, 2026
aa3ca03
Merge branch 'eng-1616-add-getconfigtree-equivalent-for-block-pros-on…
sid597 Apr 15, 2026
266558a
Merge branch 'eng-1470-test-dual-read-with-flag-on-and-fix-gapsv2' in…
sid597 Apr 15, 2026
5b4b233
fix bug similar code
sid597 Apr 15, 2026
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: 6 additions & 12 deletions apps/roam/src/components/DiscourseNodeMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@ import { getNewDiscourseNodeText } from "~/utils/formatUtils";
import { OnloadArgs } from "roamjs-components/types";
import { formatHexColor } from "./settings/DiscourseNodeCanvasSettings";
import posthog from "posthog-js";
import {
getPersonalSetting,
setPersonalSetting,
} from "~/components/settings/utils/accessors";
import { setPersonalSetting } from "~/components/settings/utils/accessors";
import { PERSONAL_KEYS } from "~/components/settings/utils/settingKeys";
import type { PersonalSettings } from "~/components/settings/utils/zodSchema";

type Props = {
textarea?: HTMLTextAreaElement;
Expand Down Expand Up @@ -420,19 +418,15 @@ export const comboToString = (combo: IKeyCombo): string => {

export const NodeMenuTriggerComponent = ({
extensionAPI,
initialValue,
}: {
extensionAPI: OnloadArgs["extensionAPI"];
initialValue: PersonalSettings["Personal node menu trigger"];
}) => {
const inputRef = useRef<HTMLInputElement>(null);
const [isActive, setIsActive] = useState(false);
const [comboKey, setComboKey] = useState<IKeyCombo>(
() =>
getPersonalSetting<IKeyCombo>([
PERSONAL_KEYS.personalNodeMenuTrigger,
]) || {
modifiers: 0,
key: "",
},
const [comboKey, setComboKey] = useState<IKeyCombo>(() =>
typeof initialValue === "object" ? initialValue : { modifiers: 0, key: "" },
);

const handleKeyDown = useCallback(
Expand Down
9 changes: 4 additions & 5 deletions apps/roam/src/components/DiscourseNodeSearchMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ import getDiscourseNodes, { DiscourseNode } from "~/utils/getDiscourseNodes";
import getDiscourseNodeFormatExpression from "~/utils/getDiscourseNodeFormatExpression";
import { Result } from "~/utils/types";
import MiniSearch from "minisearch";
import {
getPersonalSetting,
setPersonalSetting,
} from "~/components/settings/utils/accessors";
import { setPersonalSetting } from "~/components/settings/utils/accessors";
import { PERSONAL_KEYS } from "~/components/settings/utils/settingKeys";

type Props = {
Expand Down Expand Up @@ -709,12 +706,14 @@ export const renderDiscourseNodeSearchMenu = (props: Props) => {

export const NodeSearchMenuTriggerSetting = ({
onloadArgs,
initialValue,
}: {
onloadArgs: OnloadArgs;
initialValue: string;
}) => {
const extensionAPI = onloadArgs.extensionAPI;
const [nodeSearchTrigger, setNodeSearchTrigger] = useState<string>(
getPersonalSetting<string>([PERSONAL_KEYS.nodeSearchMenuTrigger]) ?? "@",
() => initialValue,
);

const handleNodeSearchTriggerChange = (
Expand Down
27 changes: 19 additions & 8 deletions apps/roam/src/components/settings/AdminPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
import Description from "roamjs-components/components/Description";
import { Select } from "@blueprintjs/select";
import {
getFeatureFlag,
setFeatureFlag,
type SettingsSnapshot,
} from "~/components/settings/utils/accessors";
import {
onSettingChange,
Expand Down Expand Up @@ -264,7 +264,11 @@ const NodeListTab = (): React.ReactElement => {
);
};

const FeatureFlagsTab = (): React.ReactElement => {
const FeatureFlagsTab = ({
featureFlags,
}: {
featureFlags: SettingsSnapshot["featureFlags"];
}): React.ReactElement => {
const legacySuggestiveModeMeta = useMemo(() => {
refreshConfigTree();
return {
Expand All @@ -276,8 +280,8 @@ const FeatureFlagsTab = (): React.ReactElement => {
};
}, []);

const [suggestiveModeEnabled, setSuggestiveModeEnabled] = useState(() =>
getFeatureFlag("Suggestive mode enabled"),
const [suggestiveModeEnabled, setSuggestiveModeEnabled] = useState(
featureFlags["Suggestive mode enabled"],
);
const [suggestiveModeUid, setSuggestiveModeUid] = useState(
legacySuggestiveModeMeta.suggestiveModeEnabledUid,
Expand Down Expand Up @@ -365,6 +369,7 @@ const FeatureFlagsTab = (): React.ReactElement => {
title="Use new settings store"
description="When enabled, accessor getters read from block props instead of the old system. Surfaces dual-write gaps during development."
featureKey="Use new settings store"
initialValue={featureFlags["Use new settings store"]}
/>

<Button
Expand All @@ -386,10 +391,16 @@ const FeatureFlagsTab = (): React.ReactElement => {
);
};

const AdminPanel = (): React.ReactElement => {
const AdminPanel = ({
featureFlags,
globalSettings,
}: {
featureFlags: SettingsSnapshot["featureFlags"];
globalSettings: SettingsSnapshot["globalSettings"];
}): React.ReactElement => {
const [selectedTabId, setSelectedTabId] = useState<TabId>("admin");
const [showSuggestiveTab, setShowSuggestiveTab] = useState(
getFeatureFlag("Suggestive mode enabled"),
featureFlags["Suggestive mode enabled"],
);

useEffect(() => {
Expand All @@ -409,7 +420,7 @@ const AdminPanel = (): React.ReactElement => {
title="Admin"
panel={
<div className="flex flex-col gap-4 p-1">
<FeatureFlagsTab />
<FeatureFlagsTab featureFlags={featureFlags} />
</div>
}
/>
Expand All @@ -427,7 +438,7 @@ const AdminPanel = (): React.ReactElement => {
id="suggestive-mode-settings"
title="Suggestive mode"
className="overflow-y-auto"
panel={<SuggestiveModeSettings />}
panel={<SuggestiveModeSettings globalSettings={globalSettings} />}
/>
)}
</Tabs>
Expand Down
23 changes: 11 additions & 12 deletions apps/roam/src/components/settings/DefaultFilters.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { Button, Intent, InputGroup } from "@blueprintjs/core";
import React, { useEffect, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import type { OnloadArgs } from "roamjs-components/types";
import type { Filters } from "roamjs-components/components/Filter";
import posthog from "posthog-js";
import {
getPersonalSetting,
setPersonalSetting,
} from "~/components/settings/utils/accessors";
import { setPersonalSetting } from "~/components/settings/utils/accessors";
import {
PERSONAL_KEYS,
QUERY_KEYS,
Expand Down Expand Up @@ -106,18 +103,15 @@ const Filter = ({

const DefaultFilters = ({
extensionAPI,
defaultFilters,
}: {
extensionAPI: OnloadArgs["extensionAPI"];
defaultFilters: Record<string, StoredFilters>;
}) => {
const [newColumn, setNewColumn] = useState("");
const [filters, setFilters] = useState(() =>
Object.fromEntries(
Object.entries(
getPersonalSetting<Record<string, StoredFilters>>([
PERSONAL_KEYS.query,
QUERY_KEYS.defaultFilters,
]) ?? {},
).map(([k, v]) => [
Object.entries(defaultFilters).map(([k, v]) => [
k,
{
includes: Object.fromEntries(
Expand All @@ -131,7 +125,12 @@ const DefaultFilters = ({
),
);

const isInitialMount = useRef(true);
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
return;
}
const serialized = Object.fromEntries(
Object.entries(filters).map(([k, v]) => [
k,
Expand All @@ -156,7 +155,7 @@ const DefaultFilters = ({
[PERSONAL_KEYS.query, QUERY_KEYS.defaultFilters],
serialized,
);
}, [filters]);
}, [filters, extensionAPI.settings]);
return (
<div
style={{
Expand Down
44 changes: 16 additions & 28 deletions apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,16 @@ import { render as renderToast } from "roamjs-components/components/Toast";
import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid";
import updateBlock from "roamjs-components/writes/updateBlock";
import getTextByBlockUid from "roamjs-components/queries/getTextByBlockUid";
import { CustomField } from "roamjs-components/components/ConfigPanels/types";
import getDiscourseNodes from "~/utils/getDiscourseNodes";
import { getConditionLabels } from "~/utils/conditionToDatalog";
import { formatHexColor } from "./DiscourseNodeCanvasSettings";
import posthog from "posthog-js";
import { getSetting, setSetting } from "~/utils/extensionSettings";
import { getStoredRelationsEnabled } from "~/utils/storedRelations";
import {
getGlobalSetting,
setGlobalSetting,
getGlobalSettings,
type SettingsSnapshot,
} from "~/components/settings/utils/accessors";
import { GLOBAL_KEYS } from "~/components/settings/utils/settingKeys";
import { RenderRoamBlock } from "~/utils/roamReactComponents";
Expand All @@ -78,12 +77,14 @@ export const RelationEditPanel = ({
back,
translatorKeys,
previewUid,
globalSettings,
}: {
editingRelationInfo: TreeNode;
back: () => void;
nodes: Record<string, { label: string; format: string; color: string }>;
translatorKeys: string[];
previewUid: string;
globalSettings: SettingsSnapshot["globalSettings"];
}) => {
const nodeFormatsByLabel = useMemo(
() =>
Expand Down Expand Up @@ -124,42 +125,21 @@ export const RelationEditPanel = ({
DEFAULT_SELECTED_RELATION,
);
const [tab, setTab] = useState(0);
const initialSourceUid = useMemo(
() =>
getGlobalSetting<string>([
GLOBAL_KEYS.relations,
editingRelationInfo.uid,
"source",
]) ?? "",
[],
);
const relation = globalSettings.Relations[editingRelationInfo.uid];
const initialSourceUid = relation?.source ?? "";
const initialSource = useMemo(
() => edgeDisplayByUid(initialSourceUid),
[initialSourceUid],
);
const [source, setSource] = useState(initialSourceUid);
const initialDestinationUid = useMemo(
() =>
getGlobalSetting<string>([
GLOBAL_KEYS.relations,
editingRelationInfo.uid,
"destination",
]) ?? "",
[],
);
const initialDestinationUid = relation?.destination ?? "";
const initialDestination = useMemo(
() => edgeDisplayByUid(initialDestinationUid),
[initialDestinationUid],
);
const [destination, setDestination] = useState(initialDestinationUid);
const [label, setLabel] = useState(editingRelationInfo.text);
const [complement, setComplement] = useState(
getGlobalSetting<string>([
GLOBAL_KEYS.relations,
editingRelationInfo.uid,
"complement",
]) ?? "",
);
const [complement, setComplement] = useState(relation?.complement ?? "");

const edgeCallback = useCallback(
(edge: cytoscape.EdgeSingular) => {
Expand Down Expand Up @@ -980,9 +960,16 @@ type Relation = {
source: string | undefined;
destination: string | undefined;
};
const DiscourseRelationConfigPanel: CustomField["options"]["component"] = ({
const DiscourseRelationConfigPanel = ({
uid,
parentUid,
globalSettings,
}: {
uid: string;
parentUid: string;
defaultValue: unknown;
title: string;
globalSettings: SettingsSnapshot["globalSettings"];
}) => {
const refreshRelations = useCallback(
() =>
Expand Down Expand Up @@ -1122,6 +1109,7 @@ const DiscourseRelationConfigPanel: CustomField["options"]["component"] = ({
back={handleBack}
translatorKeys={translatorKeys}
previewUid={previewUid}
globalSettings={globalSettings}
/>
</div>
);
Expand Down
15 changes: 14 additions & 1 deletion apps/roam/src/components/settings/ExportSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ import {
GLOBAL_KEYS,
EXPORT_KEYS,
} from "~/components/settings/utils/settingKeys";
import { type SettingsSnapshot } from "./utils/accessors";

const DiscourseGraphExport = () => {
const DiscourseGraphExport = ({
globalSettings,
}: {
globalSettings: SettingsSnapshot["globalSettings"];
}) => {
const exportBlockProps = globalSettings.Export;
const exportSettings = getExportSettingsAndUids();
const parentUid = exportSettings.exportUid;
return (
Expand All @@ -26,6 +32,7 @@ const DiscourseGraphExport = () => {
GLOBAL_KEYS.export,
EXPORT_KEYS.removeSpecialCharacters,
]}
initialValue={exportBlockProps[EXPORT_KEYS.removeSpecialCharacters]}
order={1}
uid={exportSettings.removeSpecialCharacters.uid}
parentUid={parentUid}
Expand All @@ -35,6 +42,7 @@ const DiscourseGraphExport = () => {
title="resolve block references"
description="Replaces block references in the markdown content with the block's content"
settingKeys={[GLOBAL_KEYS.export, EXPORT_KEYS.resolveBlockReferences]}
initialValue={exportBlockProps[EXPORT_KEYS.resolveBlockReferences]}
order={3}
uid={exportSettings.optsRefs.uid}
parentUid={parentUid}
Expand All @@ -43,6 +51,7 @@ const DiscourseGraphExport = () => {
title="resolve block embeds"
description="Replaces block embeds in the markdown content with the block's content tree"
settingKeys={[GLOBAL_KEYS.export, EXPORT_KEYS.resolveBlockEmbeds]}
initialValue={exportBlockProps[EXPORT_KEYS.resolveBlockEmbeds]}
order={4}
uid={exportSettings.optsEmbeds.uid}
parentUid={parentUid}
Expand All @@ -52,6 +61,7 @@ const DiscourseGraphExport = () => {
title="append referenced node"
description="If a referenced node is defined in a node's format, it will be appended to the discourse context"
settingKeys={[GLOBAL_KEYS.export, EXPORT_KEYS.appendReferencedNode]}
initialValue={exportBlockProps[EXPORT_KEYS.appendReferencedNode]}
order={6}
uid={exportSettings.appendRefNodeContext.uid}
parentUid={parentUid}
Expand All @@ -62,6 +72,7 @@ const DiscourseGraphExport = () => {
title="link type"
description="How to format links that appear in your export."
settingKeys={[GLOBAL_KEYS.export, EXPORT_KEYS.linkType]}
initialValue={exportBlockProps[EXPORT_KEYS.linkType]}
order={5}
options={["alias", "wikilinks", "roam url"]}
uid={exportSettings.linkType.uid}
Expand All @@ -72,6 +83,7 @@ const DiscourseGraphExport = () => {
title="max filename length"
description="Set the maximum name length for markdown file exports"
settingKeys={[GLOBAL_KEYS.export, EXPORT_KEYS.maxFilenameLength]}
initialValue={exportBlockProps[EXPORT_KEYS.maxFilenameLength]}
order={0}
uid={exportSettings.maxFilenameLength.uid}
parentUid={parentUid}
Expand All @@ -80,6 +92,7 @@ const DiscourseGraphExport = () => {
title="frontmatter"
description="Specify all the lines that should go to the Frontmatter of the markdown file"
settingKeys={[GLOBAL_KEYS.export, EXPORT_KEYS.frontmatter]}
initialValue={exportBlockProps[EXPORT_KEYS.frontmatter]}
order={2}
uid={exportSettings.frontmatter.uid}
parentUid={parentUid}
Expand Down
Loading
Loading