Skip to content

Commit e20bcb9

Browse files
committed
Use async.fast as a shortcut. Keep slow async around until we have tests. more precise pull block collision detection
1 parent ede4f13 commit e20bcb9

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

apps/roam/src/utils/fireQuery.ts

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ export const fireQuerySync = (args: FireQueryArgs): QueryResult[] => {
316316
}));
317317
};
318318

319-
const PROP_NAME_RE = /:\w+\/\w+\b/g;
319+
const PROP_NAME_RE = /:[a-zA-Z0-9_-]+\/[a-zA-Z0-9_-]+\b/g;
320+
const PULL_RE = /\(pull [^)]+\)/g;
320321

321322
const renamePropsInResult = (
322323
result: json | null,
@@ -372,25 +373,44 @@ const fireQuery: FireQuery = async (_args) => {
372373
}
373374

374375
let queryResults: unknown[][] = [];
376+
// for now assume fast results are equivalent to slow.
377+
// We have seen some errors in (fast) backend queries, but not so far in local fast ones.
378+
const preferSlow = false;
375379
if (local) {
376-
// look for propNames in query. Could consider looking only in pull when that exists.
377-
const propNames = new Set(
378-
[...query.matchAll(PROP_NAME_RE)].map((m) => m[0]),
379-
);
380-
const propNamesSub: Record<string, string> = Object.fromEntries(
381-
[...propNames].map((n) => [n.split("/")[1], n]),
382-
);
383-
if (Object.keys(propNamesSub).length === propNames.size) {
380+
let useSlow = preferSlow;
381+
let propNamesSub: Record<string, string> | undefined;
382+
if (preferSlow) {
383+
// keeping this code in case it turns out the fast results are more fragile than the slow ones
384+
// TODO: Remove when we have a more comprehensive test suite.
385+
const pulls = [...query.matchAll(PULL_RE)].map((r) => r[0]);
386+
if (pulls.length > 0) {
387+
// pull in base async query (vs fast or backend) returns non-namespaced names,
388+
// so there are a few possibilities of conflict,
389+
// namely: {log,version,window}/id; {graph,user}/settings; {block,user}/uid; {create,edit}/time
390+
// So look for collisions in property names in pull part of query.
391+
const propNames = new Set(
392+
[...pulls.join(" ").matchAll(PROP_NAME_RE)].map((m) => m[0]),
393+
);
394+
propNamesSub = Object.fromEntries(
395+
[...propNames].map((n) => [n.split("/")[1], n]),
396+
);
397+
useSlow = Object.keys(propNamesSub).length === propNames.size;
398+
}
399+
}
400+
if (useSlow) {
384401
// no name conflict, safe to use async query
385402
// BUT it returns non-namespaced names, so substitute prop names back
386403
queryResults = await window.roamAlphaAPI.data.async.q(query, ...inputs);
387-
queryResults = renamePropsInResult(
388-
queryResults as json,
389-
propNamesSub,
390-
) as unknown[][];
404+
if (propNamesSub !== undefined)
405+
queryResults = renamePropsInResult(
406+
queryResults as json,
407+
propNamesSub,
408+
) as unknown[][];
391409
} else {
392-
// more janky but safer
393-
queryResults = window.roamAlphaAPI.data.fast.q(query, ...inputs);
410+
queryResults = await window.roamAlphaAPI.data.async.fast.q(
411+
query,
412+
...inputs,
413+
);
394414
}
395415
} else {
396416
// eslint-disable-next-line @typescript-eslint/await-thenable

0 commit comments

Comments
 (0)