Mirror: The small sibling of the graphql package, slimmed down for client-side libraries.
1import { BREAK, Kind } from '@0no-co/graphql.web';
2import { getEnterLeaveForKind } from 'graphql/language/visitor';
3
4export { getEnterLeaveForKind, getVisitFn } from 'graphql/language/visitor';
5export { BREAK, visit, Kind } from '@0no-co/graphql.web';
6
7export function visitInParallel(visitors) {
8 const skipping = new Array(visitors.length).fill(null);
9 const mergedVisitor = Object.create(null);
10
11 for (const kind of Object.values(Kind)) {
12 let hasVisitor = false;
13 const enterList = new Array(visitors.length).fill(undefined);
14 const leaveList = new Array(visitors.length).fill(undefined);
15
16 for (let i = 0; i < visitors.length; ++i) {
17 const { enter, leave } = getEnterLeaveForKind(visitors[i], kind);
18 hasVisitor = hasVisitor || enter != null || leave != null;
19 enterList[i] = enter;
20 leaveList[i] = leave;
21 }
22
23 if (!hasVisitor) {
24 continue;
25 }
26
27 const mergedEnterLeave = {
28 enter(...args) {
29 const node = args[0];
30 for (let i = 0; i < visitors.length; i++) {
31 if (skipping[i] === null) {
32 const result = enterList[i] && enterList[i].apply(visitors[i], args);
33 if (result === false) {
34 skipping[i] = node;
35 } else if (result === BREAK) {
36 skipping[i] = BREAK;
37 } else if (result !== undefined) {
38 return result;
39 }
40 }
41 }
42 },
43 leave(...args) {
44 const node = args[0];
45 for (let i = 0; i < visitors.length; i++) {
46 if (skipping[i] === null) {
47 const result = leaveList[i] && leaveList[i].apply(visitors[i], args);
48 if (result === BREAK) {
49 skipping[i] = BREAK;
50 } else if (result !== undefined && result !== false) {
51 return result;
52 }
53 } else if (skipping[i] === node) {
54 skipping[i] = null;
55 }
56 }
57 },
58 };
59
60 mergedVisitor[kind] = mergedEnterLeave;
61 }
62
63 return mergedVisitor;
64}