( // Might be plain array or any observable array. This allows creating nested queries of previously created queries // It is getter as source value might be computed value, so we want to observe getting it (especially in nested queries) getSource: () => MaybeObservableArray<Entity<Data, View>>, queryConfig: EntityQueryConfig<Data, View>, store: EntityStore<Data, View> )
| 88 | * It is also lazy - it will not calculate results until they are needed. |
| 89 | */ |
| 90 | export function createEntityQuery<Data, View>( |
| 91 | // Might be plain array or any observable array. This allows creating nested queries of previously created queries |
| 92 | // It is getter as source value might be computed value, so we want to observe getting it (especially in nested queries) |
| 93 | getSource: () => MaybeObservableArray<Entity<Data, View>>, |
| 94 | queryConfig: EntityQueryConfig<Data, View>, |
| 95 | store: EntityStore<Data, View> |
| 96 | ): Collection<Data, View> { |
| 97 | const { definition } = store; |
| 98 | const { filter, sort, name: queryName } = queryConfig; |
| 99 | |
| 100 | const { |
| 101 | config: { functionalFilterCheck }, |
| 102 | } = definition; |
| 103 | |
| 104 | if (!filter && !sort) { |
| 105 | throw new Error( |
| 106 | `Either filter or sort is needed to be provided to query. If no sort or filter is needed, use .all property.` |
| 107 | ); |
| 108 | } |
| 109 | |
| 110 | const sortConfig = resolveSortInput(sort); |
| 111 | |
| 112 | function getQueryKeyBase() { |
| 113 | const parts: string[] = [definition.config.name]; |
| 114 | |
| 115 | if (queryName) { |
| 116 | parts.push(queryName); |
| 117 | } |
| 118 | |
| 119 | if (filter) { |
| 120 | if (typeof filter === "function") { |
| 121 | parts.push(`filter()`); |
| 122 | } else { |
| 123 | parts.push(`filter({${Object.keys(filter).join(",")}})`); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | if (sortConfig) { |
| 128 | parts.push(`sort()[${sortConfig.direction}]`); |
| 129 | } |
| 130 | |
| 131 | return parts.join("__"); |
| 132 | } |
| 133 | |
| 134 | const queryKeyBase = getQueryKeyBase(); |
| 135 | |
| 136 | /** |
| 137 | * Create filter cache only for functional filter. |
| 138 | * |
| 139 | * Simple query filter eg { user_id: "foo" } does not require it as simpleQuery is already cached |
| 140 | * and observable. |
| 141 | * |
| 142 | * Also it is very often used resulting easily in 100k+ calls on production data (we really dont want so many cached functions |
| 143 | * created for already cached list) |
| 144 | */ |
| 145 | const cachedFilterForFunctionalFilter = |
| 146 | typeof filter === "function" |
| 147 | ? /** |
no test coverage detected