(add-branch-node {:com.wsscode.pathom3.connect.planner/keys [root] :as graph}
{:com.wsscode.pathom3.connect.planner/keys [branch-type]
:as env}
{:com.wsscode.pathom3.connect.planner/keys [node-id]})
Given a branch node is the root, this function will add the new node as part of that branch node. If the node is a repeating dynamic node it will cause the new node to be collapsed into the already existent dynamic node.
Given a branch node is the root, this function will add the new node as part of that branch node. If the node is a repeating dynamic node it will cause the new node to be collapsed into the already existent dynamic node.
(add-snapshot! graph
{:com.wsscode.pathom3.connect.planner/keys [snapshots*]}
event-details)
(add-unreachable-attr graph attr)
Add attribute to unreachable list
Add attribute to unreachable list
(all-attribute-resolvers {:com.wsscode.pathom3.connect.indexes/keys [index-oir]}
attr)
Gets the op name for all resolvers available for a given attribute.
Gets the op name for all resolvers available for a given attribute.
(all-node-ids graph)
Return all node-ids from the graph.
Return all node-ids from the graph.
(assoc-node graph node-id k v)
Set attribute k about node-id. Only assoc when node exists, otherwise its a noop.
Set attribute k about node-id. Only assoc when node exists, otherwise its a noop.
(attributes-with-nodes {:com.wsscode.pathom3.connect.planner/keys [index-attrs]}
attrs)
Filter attributes that have attached nodes.
Filter attributes that have attached nodes.
(branch-node? node)
Returns true when the node is a branch node type.
Returns true when the node is a branch node type.
(collapse-and-nodes graph target-node-id node-id)
Collapse AND node next-node into AND node target-node-id.
Collapse AND node next-node into AND node target-node-id.
(collapse-nodes-chain graph target-node-id node-id)
Merge chained nodes:
A -> B
A is target node, B is the node, this collapses things and only A will exist after.
Merge chained nodes: A -> B A is target node, B is the node, this collapses things and only A will exist after.
(collapse-set-node-run-next graph target-node-id run-next)
Like set-node-run-next, but also checks if the target and next node are the same resolver, if so, this fn will collapse those nodes.
Like set-node-run-next, but also checks if the target and next node are the same resolver, if so, this fn will collapse those nodes.
(collect-nested-resolver-names graph env node)
(collect-nested-resolver-names graph
env
{:com.wsscode.pathom3.connect.planner/keys
[node-id]}
syms)
From a node, scans all descendents (run next and branches) and collect the op-name of every resolver call found.
From a node, scans all descendents (run next and branches) and collect the op-name of every resolver call found.
(compute-all-node-depths graph)
Return graph with node-depth calculated for all nodes.
Return graph with node-depth calculated for all nodes.
(compute-and-unless-root-is-ancestor
{:com.wsscode.pathom3.connect.planner/keys [root] :as graph}
env
{:com.wsscode.pathom3.connect.planner/keys [node-id]})
(compute-attribute-graph
{:com.wsscode.pathom3.connect.planner/keys [unreachable-paths] :as graph}
{:com.wsscode.pathom3.connect.planner/keys [available-data attr-deps-trail]
:com.wsscode.pathom3.connect.indexes/keys [index-oir]
{attr :key :as ast} :edn-query-language.ast/node
:as env})
Compute the run graph for a given attribute.
Compute the run graph for a given attribute.
(compute-attribute-graph* {:com.wsscode.pathom3.connect.planner/keys [root]
:as graph}
{:com.wsscode.pathom3.connect.indexes/keys [index-oir]
:com.wsscode.pathom3.attribute/keys [attribute]
:as env})
(compute-input-resolvers-graph
graph
{:com.wsscode.pathom3.connect.planner/keys [available-data] :as env}
input
resolvers)
(compute-missing-chain graph
{:com.wsscode.pathom3.connect.planner/keys
[graph-before-missing-chain available-data]
:as env}
missing
resolvers)
Start a recursive call to process the dependencies required by the resolver. It sets the ::run-next data at the env, it will be used to link the nodes after they are created in the process.
Start a recursive call to process the dependencies required by the resolver. It sets the ::run-next data at the env, it will be used to link the nodes after they are created in the process.
(compute-nested-node-details {ast :edn-query-language.ast/node :as env})
Use AST children nodes and resolver provides data to compute the nested requirements for dynamic nodes.
Use AST children nodes and resolver provides data to compute the nested requirements for dynamic nodes.
(compute-node-depth graph node-id)
Calculate depth of node-id, this returns a graph in which that node has the key ::node-depth associated in the node. The depth is calculated by following the ::node-parents chain, in the process all the parent node depths are also calculated and set, this makes it efficient to scan the list calculating the depths, given each node will be visited at max once.
Calculate depth of node-id, this returns a graph in which that node has the key ::node-depth associated in the node. The depth is calculated by following the ::node-parents chain, in the process all the parent node depths are also calculated and set, this makes it efficient to scan the list calculating the depths, given each node will be visited at max once.
(compute-resolver-graph
{:com.wsscode.pathom3.connect.planner/keys [unreachable-resolvers] :as graph}
env
resolver)
(compute-root-and {:com.wsscode.pathom3.connect.planner/keys [root] :as graph}
env
{:com.wsscode.pathom3.connect.planner/keys [node-id]
:as node})
(compute-root-branch
{:com.wsscode.pathom3.connect.planner/keys [root] :as graph}
{:com.wsscode.pathom3.connect.planner/keys [branch-type] :as env}
{:com.wsscode.pathom3.connect.planner/keys [node-id]}
branch-node-factory)
(compute-root-or {:com.wsscode.pathom3.connect.planner/keys [root] :as graph}
{:com.wsscode.pathom3.attribute/keys [attribute] :as env}
{:com.wsscode.pathom3.connect.planner/keys [node-id] :as node})
(compute-root-or {:com.wsscode.pathom3.connect.planner/keys [root] :as graph}
{:com.wsscode.pathom3.attribute/keys [attribute] :as env}
{:com.wsscode.pathom3.connect.planner/keys [node-id] :as node}
leave-node-id)
Combine the root node with a new graph using an OR. This is used to combine nodes to allow the runner to choose between paths. This happens when there are multiple possibilities to reach some attribute.
When leave-node-id is present, this means there is a chance the combination nodes have the same root, because of attribute re-use. In this case, there will be an AND node that should be an OR. In this case the algorithm checks if that's the case, and if so it does convert the AND node into an OR node.
Combine the root node with a new graph using an OR. This is used to combine nodes to allow the runner to choose between paths. This happens when there are multiple possibilities to reach some attribute. When leave-node-id is present, this means there is a chance the combination nodes have the same root, because of attribute re-use. In this case, there will be an AND node that should be an OR. In this case the algorithm checks if that's the case, and if so it does convert the AND node into an OR node.
(compute-run-graph env)
(compute-run-graph graph env)
Generates a run plan for a given environment, the environment should contain the indexes in it (::pc/index-oir and ::pc/index-resolvers). It computes a plan to execute one level of an AST, the AST must be provided via the key :edn-query-language.ast/node.
(compute-run-graph (assoc indexes :edn-query-language.ast/node ...))
The resulting graph will look like this:
{::nodes {1 {::pco/op-name a
::node-id 1
::requires {:a {}}
::input {}
::source-for-attrs #{:a}
::node-parents #{3}}
2 {::pco/op-name b
::node-id 2
::requires {:b {}}
::input {}
::source-for-attrs #{:b}
::node-parents #{3}}
3 {::node-id 3
::requires {:b {} :a {} :c {}}
::run-and #{2 1 4}}
4 {::pco/op-name c
::node-id 4
::requires {:c {}}
::input {}
::source-for-attrs #{:c}
::node-parents #{3}}}
::index-resolver->nodes {a #{1} b #{2} c #{4}}
::unreachable-resolvers #{}
::unreachable-attrs #{}
::index-attrs {:a 1 :b 2 :c 4}
::root 3}
Generates a run plan for a given environment, the environment should contain the indexes in it (::pc/index-oir and ::pc/index-resolvers). It computes a plan to execute one level of an AST, the AST must be provided via the key :edn-query-language.ast/node. (compute-run-graph (assoc indexes :edn-query-language.ast/node ...)) The resulting graph will look like this: {::nodes {1 {::pco/op-name a ::node-id 1 ::requires {:a {}} ::input {} ::source-for-attrs #{:a} ::node-parents #{3}} 2 {::pco/op-name b ::node-id 2 ::requires {:b {}} ::input {} ::source-for-attrs #{:b} ::node-parents #{3}} 3 {::node-id 3 ::requires {:b {} :a {} :c {}} ::run-and #{2 1 4}} 4 {::pco/op-name c ::node-id 4 ::requires {:c {}} ::input {} ::source-for-attrs #{:c} ::node-parents #{3}}} ::index-resolver->nodes {a #{1} b #{2} c #{4}} ::unreachable-resolvers #{} ::unreachable-attrs #{} ::index-attrs {:a 1 :b 2 :c 4} ::root 3}
(convert-and-to-or graph
{:com.wsscode.pathom3.attribute/keys [attribute]}
node-id)
(create-branch-node {:com.wsscode.pathom3.connect.planner/keys [root] :as graph}
env
node
branch-node)
(create-resolver-node graph
{:com.wsscode.pathom3.connect.planner/keys [run-next input
source-sym]
:com.wsscode.pathom3.attribute/keys [attribute]
:com.wsscode.pathom3.connect.operation/keys [op-name]
ast :edn-query-language.ast/node
:as env})
Create a new node representative to run a given resolver.
Create a new node representative to run a given resolver.
(entry-ast graph k)
Find AST node a given entry from the source AST.
Find AST node a given entry from the source AST.
(extend-resolver-node
{:com.wsscode.pathom3.connect.planner/keys [index-resolver->nodes] :as graph}
{:com.wsscode.pathom3.attribute/keys [attribute]
ast :edn-query-language.ast/node}
resolver-sym)
(find-attribute-resolver-in-successors graph node-id attribute)
Find the nodes that get the data required for the require in the OR node.
Find the nodes that get the data required for the require in the OR node.
(find-branch-node-to-merge
{:com.wsscode.pathom3.connect.planner/keys [root] :as graph}
{:com.wsscode.pathom3.connect.planner/keys [branch-type]}
{:com.wsscode.pathom3.connect.planner/keys [node-id]})
Given some branch node, tries to find a node with a dynamic resolver that's the same sym as the node in node-id.
Given some branch node, tries to find a node with a dynamic resolver that's the same sym as the node in node-id.
(find-dependent-ancestor graph env node-id)
For a given node N, find which node is responsible for N dependencies. This is done by traversing the parents (but only when its run-next) and find tha latest in the chain.
For a given node N, find which node is responsible for N dependencies. This is done by traversing the parents (but only when its run-next) and find tha latest in the chain.
(find-dependent-ancestor* graph env required path)
Traverse path until all required data is fulfilled. Returns node in which the data is done. If it can't fulfill all the data, returns nil.
Traverse path until all required data is fulfilled. Returns node in which the data is done. If it can't fulfill all the data, returns nil.
(find-direct-node-successors
{:com.wsscode.pathom3.connect.planner/keys [run-next] :as node})
Direct successors of node, branch nodes and run-next, in case of branch nodes the branches will always come before the run-next.
Direct successors of node, branch nodes and run-next, in case of branch nodes the branches will always come before the run-next.
(find-furthest-ancestor graph node-id)
Traverse node node-parent chain and returns the most distant resolver ancestor of node id. This only walks though resolver nodes, branch nodes are removed.
Traverse node node-parent chain and returns the most distant resolver ancestor of node id. This only walks though resolver nodes, branch nodes are removed.
(find-leaf-node graph node)
Traverses all run-next still it reaches a leaf.
Traverses all run-next still it reaches a leaf.
(find-missing-ancestor graph missing)
Find the first common AND node ancestors from missing list, missing is a list of attributes
Find the first common AND node ancestors from missing list, missing is a list of attributes
(find-node-direct-ancestor-chain graph node-id)
Computes ancestor chain for a given node, it only walks as long as there is a single parent on the node, if there is a fork (multiple node-parents) it will stop.
Computes ancestor chain for a given node, it only walks as long as there is a single parent on the node, if there is a fork (multiple node-parents) it will stop.
(find-node-for-attribute-in-chain
graph
{:com.wsscode.pathom3.attribute/keys [attribute] :as env}
root)
Walks the graph run next chain until it finds the node that's providing the attribute.
Walks the graph run next chain until it finds the node that's providing the attribute.
(find-run-next-descendants graph
{:com.wsscode.pathom3.connect.planner/keys
[node-id]})
Return descendants by waling the run-next
Return descendants by waling the run-next
(first-common-ancestor graph node-ids)
Find first common node ancestor given a list of node ids.
Find first common node ancestor given a list of node ids.
(get-attribute-node graph attribute)
Find the node for attribute in attribute index.
Find the node for attribute in attribute index.
(get-root-node {:com.wsscode.pathom3.connect.planner/keys [root] :as graph})
Returns the root node of the graph.
Returns the root node of the graph.
(graph-provides {:com.wsscode.pathom3.connect.planner/keys [index-attrs]})
Get a set with all provided attributes from the graph.
Get a set with all provided attributes from the graph.
(include-node graph
env
{:com.wsscode.pathom3.connect.planner/keys [node-id] :as node})
Add new node to the graph, this add the node and the index of in ::index-syms.
Add new node to the graph, this add the node and the index of in ::index-syms.
(inject-index-nested-provides indexes
{:com.wsscode.pathom3.attribute/keys [attribute]
:com.wsscode.pathom3.connect.operation/keys
[op-name]
:as env})
(mark-attribute-process-sub-query graph {:keys [key children query]})
Add information about attribute that is present but requires further processing due to subquery, this is created so the runner can quickly know which attributes need to have the subquery processing done.
Add information about attribute that is present but requires further processing due to subquery, this is created so the runner can quickly know which attributes need to have the subquery processing done.
(mark-node-unreachable previous-graph
graph
{:com.wsscode.pathom3.connect.planner/keys
[unreachable-resolvers unreachable-paths]}
env)
(merge-missing-chain graph
graph'
{:com.wsscode.pathom3.connect.planner/keys [available-data]
:as env}
missing
missing-flat
optionals)
(merge-nested-missing-ast
graph
{:com.wsscode.pathom3.connect.planner/keys [available-data resolvers] :as env}
missing)
(merge-node-expects graph
target-node-id
{:com.wsscode.pathom3.connect.planner/keys [expects]})
Merge requires from node into target-node-id.
Merge requires from node into target-node-id.
(merge-node-input graph
target-node-id
{:com.wsscode.pathom3.connect.planner/keys [input]})
Merge input from node into target-node-id.
Merge input from node into target-node-id.
(merge-nodes-foreign-ast graph
target-node-id
{:com.wsscode.pathom3.connect.planner/keys
[foreign-ast]})
Merge the foreign-ast from two dynamic nodes, the operations adds each children from node into foreign-ast of the target node. This uses the requires to detect if some attribute is already on the query, so this must be called before merging requires to get the correct behavior.
Merge the foreign-ast from two dynamic nodes, the operations adds each children from node into foreign-ast of the target node. This uses the requires to detect if some attribute is already on the query, so this must be called before merging requires to get the correct behavior.
(merge-nodes-params graph
target-node-id
{:com.wsscode.pathom3.connect.planner/keys [params]})
Merge params of nodes, in case of conflicting keys a warning will be generated.
Merge params of nodes, in case of conflicting keys a warning will be generated.
(merge-nodes-run-next {:com.wsscode.pathom3.connect.planner/keys [root]
:as graph}
env
target-node-id
{:com.wsscode.pathom3.connect.planner/keys [run-next]})
Updates target-node-id run-next with the run-next of the last argument. This will do an AND branch operation with node-id run-next and run-next, updating the reference of node-id run-next.
Updates target-node-id run-next with the run-next of the last argument. This will do an AND branch operation with node-id run-next and run-next, updating the reference of node-id run-next.
(next-node-id {:com.wsscode.pathom3.connect.planner/keys [id-counter]})
Return the next node ID in the system, its an incremental number
Return the next node ID in the system, its an incremental number
(node->label node)
Return a string representation for the node, for resolver nodes this is the symbol, branch nodes get AND / OR respectively.
Return a string representation for the node, for resolver nodes this is the symbol, branch nodes get AND / OR respectively.
(node-ancestors graph node-id)
Return all node ancestors. The order of the output will go from closest to farthest nodes, like breathing out of the current node.
Return all node ancestors. The order of the output will go from closest to farthest nodes, like breathing out of the current node.
(node-ancestors-paths graph node-id)
Return all node ancestors paths. For when multiple parent paths in a node, there will be a new path in the output.
Return all node ancestors paths. For when multiple parent paths in a node, there will be a new path in the output.
(node-branches node)
Return node branches, which can be the ::run-and or the ::run-or part of the node.
Return node branches, which can be the ::run-and or the ::run-or part of the node.
(node-depth graph node-id)
Compute the depth for node-id and return it.
Compute the depth for node-id and return it.
(node-kind node)
Return a keyword describing the type of the node.
Return a keyword describing the type of the node.
(node-parent-run-next graph
{:com.wsscode.pathom3.connect.planner/keys [node-parents
node-id]})
Check from the node parents which links using run-next. Return nil when not found.
Check from the node parents which links using run-next. Return nil when not found.
(node-successors graph node-id)
Find successor nodes of node-id, node-id is included in the list. This will add branch nodes before run-next nodes. Returns a lazy sequence that traverse the graph as items are requested.
Find successor nodes of node-id, node-id is included in the list. This will add branch nodes before run-next nodes. Returns a lazy sequence that traverse the graph as items are requested.
(node-with-resolver-config graph
env
{:com.wsscode.pathom3.connect.planner/keys [node-id]
:as node'})
Get the node plus the resolver config, when the node has an op-name. If node is not a resolver not it returns nil.
Get the node plus the resolver config, when the node has an op-name. If node is not a resolver not it returns nil.
(optimize-merge? graph {:com.wsscode.pathom3.connect.planner/keys [node-id]})
Check if node and graph point to same run-next.
Check if node and graph point to same run-next.
(params-conflicting-keys m1 m2)
Find conflicting keys between maps m1 and m2, same keys with same values are not considered conflicting keys.
Find conflicting keys between maps m1 and m2, same keys with same values are not considered conflicting keys.
(previous-node-depth graph current-node-id previous-node-id)
Get previous node depth, normally it uses the ::node-depth of previous node. There is a special case, when the previous node is a branch node and the current node is the run-next of the previous, in this case the previous depth should return the node chain depth instead, so the depth of the run-next goes after the branch dependencies.
Get previous node depth, normally it uses the ::node-depth of previous node. There is a special case, when the previous node is a branch node and the current node is the run-next of the previous, in this case the previous depth should return the node chain depth instead, so the depth of the run-next goes after the branch dependencies.
(remove-branch-node-parents graph node-id)
When node-id is a branch node, remove all node-parents associated from its children.
When node-id is a branch node, remove all node-parents associated from its children.
(remove-from-parent-branches graph
{:com.wsscode.pathom3.connect.planner/keys
[node-id node-parents]})
(remove-node graph node-id)
Remove a node from the graph. In case of resolver nodes it also removes them from the ::index-syms and after node references.
Remove a node from the graph. In case of resolver nodes it also removes them from the ::index-syms and after node references.
(required-input-reachable?
{:com.wsscode.pathom3.connect.planner/keys [index-attrs] :as graph}
env
required)
After running a sub graph for dependencies, the planner checks if all required inputs are met in the new sub graph. In case of nested dependencies, a new graph must run to verify that the sub query dependencies are possible to met, otherwise the path is discarded.
After running a sub graph for dependencies, the planner checks if all required inputs are met in the new sub graph. In case of nested dependencies, a new graph must run to verify that the sub query dependencies are possible to met, otherwise the path is discarded.
(reset-env env)
Restore the original environment sent to run-graph! Use this for nested graphs that need a clean environment.
Restore the original environment sent to run-graph! Use this for nested graphs that need a clean environment.
(resolver-node-requires-attribute? {:com.wsscode.pathom3.connect.planner/keys
[expects sym]}
attribute)
(resolver-provides {:com.wsscode.pathom3.connect.planner/keys [source-sym]
:as env})
Get resolver provides from environment source symbol.
Get resolver provides from environment source symbol.
(resolvers-optionals env resolvers)
Merge the optionals from a collection of resolver symbols.
Merge the optionals from a collection of resolver symbols.
(root-execution-node? graph node-id)
A node is a root execution is a node without any ancestors, or all ancestors are branch nodes.
A node is a root execution is a node without any ancestors, or all ancestors are branch nodes.
(runner-node-sym env resolver-name)
Find the runner symbol for a resolver, on normal resolvers that is the resolver symbol, but for foreign resolvers it uses its ::p.c.o/dynamic-name.
Find the runner symbol for a resolver, on normal resolvers that is the resolver symbol, but for foreign resolvers it uses its ::p.c.o/dynamic-name.
(same-resolver? node1 node2)
Check if node1 and node2 have the same resolver name.
Check if node1 and node2 have the same resolver name.
(set-node-run-next graph target-node-id run-next)
Set the node run next value and add the node-parent counter part. Noop if target and run next are the same node.
Set the node run next value and add the node-parent counter part. Noop if target and run next are the same node.
(set-node-run-next* graph node-id run-next)
Update the node-id run-next value, if run-next is nil the attribute will be removed from the map.
Update the node-id run-next value, if run-next is nil the attribute will be removed from the map.
(set-node-source-for-attrs graph
{:com.wsscode.pathom3.attribute/keys [attribute]
:as env})
(sub-required-input-reachable?
{:com.wsscode.pathom3.connect.planner/keys [index-attrs] :as graph}
{:com.wsscode.pathom3.connect.planner/keys [available-data] :as env}
attr
sub)
(transfer-node-parents graph
target-node-id
{:com.wsscode.pathom3.connect.planner/keys
[node-parents]})
Set the run next for each after node to be target-node-id.
Set the run next for each after node to be target-node-id.
(transfer-node-source-attrs graph
target-node-id
{:com.wsscode.pathom3.connect.planner/keys
[source-for-attrs]})
Pulls source for attributes from node to target-node-id, also updates the attributes index to respect the transfer.
Pulls source for attributes from node to target-node-id, also updates the attributes index to respect the transfer.
(unreachable-attrs-after-missing-check env unreachable-resolvers still-missing)
Mark which attributes are unreachable, given the unreachable resolvers.
This makes sure we don't mark an attribute as unreachable when it still have possibilities to run.
A special case is nested requirements, since they were already part of a separated computation we can always merge those in.
Mark which attributes are unreachable, given the unreachable resolvers. This makes sure we don't mark an attribute as unreachable when it still have possibilities to run. A special case is nested requirements, since they were already part of a separated computation we can always merge those in.
(update-node graph node-id k f)
(update-node graph node-id k f v)
(update-node graph node-id k f v v2)
(update-node graph node-id k f v v2 v3)
(update-node graph node-id k f v v2 v3 & args)
Update a given node in a graph, like Clojure native update.
Update a given node in a graph, like Clojure native update.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close