(
steps: Step[],
{
vars,
viewPlans,
preparedViews = {},
}: {
vars: any;
viewPlans: Record<string, { steps: Step[] }>;
preparedViews?: Record<string, ViewEntity[] | ViewEntity>;
}
)
| 92 | } |
| 93 | |
| 94 | private async executeSteps( |
| 95 | steps: Step[], |
| 96 | { |
| 97 | vars, |
| 98 | viewPlans, |
| 99 | preparedViews = {}, |
| 100 | }: { |
| 101 | vars: any; |
| 102 | viewPlans: Record<string, { steps: Step[] }>; |
| 103 | preparedViews?: Record<string, ViewEntity[] | ViewEntity>; |
| 104 | } |
| 105 | ): Promise<ViewEntity[] | ViewEntity> { |
| 106 | // Ensure an entityStack is always present |
| 107 | vars.entityStack = vars.entityStack || []; |
| 108 | let results: ViewEntity[] = []; |
| 109 | let collectionName: string | undefined; |
| 110 | let candidateIterator: |
| 111 | | Iterable<ViewEntity> |
| 112 | | AsyncIterable<ViewEntity> |
| 113 | | undefined; |
| 114 | for (const step of steps) { |
| 115 | switch (step.type) { |
| 116 | case 'PREPARE_VIEW': { |
| 117 | const alias = `view_${step.viewId}`; |
| 118 | // If we've already prepared the view, skip |
| 119 | if (alias in preparedViews) { |
| 120 | break; |
| 121 | } |
| 122 | const { steps } = viewPlans[step.viewId]; |
| 123 | const viewResults = await this.executeSteps(steps, { |
| 124 | vars, |
| 125 | viewPlans, |
| 126 | preparedViews, |
| 127 | }); |
| 128 | preparedViews[alias] = viewResults; |
| 129 | break; |
| 130 | } |
| 131 | case 'RESOLVE_FROM_VIEW': { |
| 132 | const viewKey = `view_${step.viewId}`; |
| 133 | const view = preparedViews[viewKey]; |
| 134 | if (!view) { |
| 135 | throw new Error(`View ${step.viewId} not found`); |
| 136 | } |
| 137 | if (!Array.isArray(view)) |
| 138 | throw new InvalidResultCardinalityError('many', 'one'); |
| 139 | const boundFilters = bindVariablesInFilters( |
| 140 | step.filter, |
| 141 | // When resolving from a view, there should be no other view variables |
| 142 | // If we error here, possibly re-add slow entity flattening |
| 143 | vars |
| 144 | ); |
| 145 | results = [...view]; |
| 146 | for (const filter of boundFilters) { |
| 147 | results = VAC.resolveQueryFromView(results, filter); |
| 148 | } |
| 149 | candidateIterator = results; |
| 150 | break; |
| 151 | } |
no test coverage detected