Skip to content
Draft
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
56 changes: 50 additions & 6 deletions apps/roam/src/utils/fireQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import predefinedSelections, {
import { DEFAULT_RETURN_NODE } from "./parseQuery";
import { DiscourseNode } from "./getDiscourseNodes";
import { DiscourseRelation } from "./getDiscourseRelations";
import type { json } from "./getBlockProps";
import nanoid from "nanoid";

export type QueryArgs = {
Expand All @@ -30,6 +31,7 @@ type RelationInQuery = {
export type FireQueryArgs = QueryArgs & {
isCustomEnabled?: boolean;
customNode?: string;
local?: boolean;
context?: {
relationsInQuery?: RelationInQuery[];
customNodes?: DiscourseNode[];
Expand Down Expand Up @@ -314,8 +316,30 @@ export const fireQuerySync = (args: FireQueryArgs): QueryResult[] => {
}));
};

const PROP_NAME_RE = /:\w+\/\w+\b/g;

const renamePropsInResult = (
result: json | null,
mapping: Record<string, string>,
): json | null => {
const rename = (x: json | null): json | null => {
if (Array.isArray(x)) return x.map(rename);
if (x === null || x === undefined) return x;
if (typeof x === "object") {
return Object.fromEntries(
Object.entries(x as object).map(([k, v]) => [
mapping[k] || k,
rename(v),
]),
);
}
return x;
};
return rename(result);
};

const fireQuery: FireQuery = async (_args) => {
const { isCustomEnabled, customNode, ...args } = _args;
const { isCustomEnabled, customNode, local, ...args } = _args;

const { query, formatResult, inputs } = isCustomEnabled
? {
Expand Down Expand Up @@ -347,11 +371,31 @@ const fireQuery: FireQuery = async (_args) => {
console.groupEnd();
}

//@ts-ignore - todo add async q to roamjs-components
const queryResults = await window.roamAlphaAPI.data.backend.q(
query,
...inputs,
);
let queryResults: unknown[][] = [];
if (local) {
// look for propNames in query. Could consider looking only in pull when that exists.
const propNames = new Set(
[...query.matchAll(PROP_NAME_RE)].map((m) => m[0]),
);
const propNamesSub: Record<string, string> = Object.fromEntries(
[...propNames].map((n) => [n.split("/")[1], n]),
);
if (Object.keys(propNamesSub).length === propNames.size) {
// no name conflict, safe to use async query
// BUT it returns non-namespaced names, so substitute prop names back
queryResults = await window.roamAlphaAPI.data.async.q(query, ...inputs);
queryResults = renamePropsInResult(
queryResults as json,
propNamesSub,
) as unknown[][];
} else {
// more janky but safer
queryResults = window.roamAlphaAPI.data.fast.q(query, ...inputs);
}
} else {
// eslint-disable-next-line @typescript-eslint/await-thenable
queryResults = await window.roamAlphaAPI.data.backend.q(query, ...inputs); // ts-ignore
}

if (nodeEnv === "development") {
console.timeEnd(`Query - ${queryId}`);
Expand Down
2 changes: 1 addition & 1 deletion apps/roam/src/utils/getExportTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ const getExportTypes = ({
);
};
const getRelationData = () =>
getRelationDataUtil(allRelations, nodeLabelByType);
getRelationDataUtil({ allRelations, nodeLabelByType, local: true });

const getJsonData = async () => {
const grammar = allRelations.map(({ label, destination, source }) => ({
Expand Down
18 changes: 12 additions & 6 deletions apps/roam/src/utils/getRelationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import type { DiscourseRelation } from "./getDiscourseRelations";

// lifted from getExportTypes

export const getRelationDataUtil = async (
allRelations: DiscourseRelation[],
nodeLabelByType: Record<string, string>,
) =>
export const getRelationDataUtil = async ({
allRelations,
nodeLabelByType,
local,
}: {
allRelations: DiscourseRelation[];
nodeLabelByType: Record<string, string>;
local?: boolean;
}) =>
Promise.all(
allRelations
.filter(
Expand All @@ -23,6 +28,7 @@ export const getRelationDataUtil = async (
? []
: fireQuery({
returnNode: sourceLabel,
local,
conditions: [
{
relation: s.label,
Expand Down Expand Up @@ -50,13 +56,13 @@ export const getRelationDataUtil = async (
}),
).then((r) => r.flat());

const getRelationData = async () => {
const getRelationData = async (local?: boolean) => {
const allRelations = getDiscourseRelations();
const allNodes = getDiscourseNodes(allRelations);
const nodeLabelByType = Object.fromEntries(
allNodes.map((a) => [a.type, a.text]),
);
return await getRelationDataUtil(allRelations, nodeLabelByType);
return await getRelationDataUtil({ allRelations, nodeLabelByType, local });
};

export default getRelationData;
2 changes: 1 addition & 1 deletion apps/roam/src/utils/migrateRelations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const migrateRelations = async (dryRun = false): Promise<number> => {
const authorized = getSetting("use-reified-relations");
if (!authorized) return 0;
const processed = new Set<string>();
const relationData = await getRelationData();
const relationData = await getRelationData(true);
let numProcessed = 0;
for (const rel of relationData) {
const key = `${rel.source}:${rel.relUid}:${rel.target}`;
Expand Down