What
Currently we have a set of functions to go from a selector expressed as IPLD (eg datamodel.Node) to a compiled selector that we hand to traversal functions.
There are a number of reasons we might want to go the other way. For example, to serialize the state of a traversal in the middle. Or to serialize selectors for the purpose of comparison.
Currently, based on how these selectors are implemented, it's relatively trivial to write a decompile for most of the selectors. However, explore recursive is very tricky. The reason is while traversing intermediate nodes between an ExploreRecursive and an ExploreRecursiveEdge, there is a compiled selector that we can execute (currently just ExploreRecursive), but no obvious decompiled form of it.
Consider this selector chain:
ExploreRecursive(limit: 10) -> ExploreFields(A) -> ExploreFields(B) -> ExploreRecursiveEdge
How do we decompile a selector for the point in the traversal when we have followed ExploreFields(A) but not ExploreFields(B)?
At first glance, one way to "decompile" this selector would be to simply defer the insertion of ExploreRecursive until the first ExploreRecursiveEdge and then put the ExploreRecursive in at that point with a decremented limit (if we're not doing RecursionLimitNone). So we get something like:
ExploreFields(B) -> ExploreRecursive(limit: 9) -> ExploreFields(A) -> ExploreFields(B) -> ExploreRecursiveEdge
The problem here is the StopAt condition on ExploreRecursive.
ExploreRecursive(limit: 10, stopAt: Qmz...) -> ExploreFields(A) -> ExploreFields(B) -> ExploreRecursiveEdge
If ExploreFields(B) when applied to the underlying data yields the link Qmz... that triggers the StopAt condition, then the approach above no longer works:
ExploreFields(B) -> ExploreRecursive(limit: 9, stopAt: Qmz....) -> ExploreFields(A) -> ExploreFields(B) -> ExploreRecursiveEdge
is not the correct selector, as it doesn't stop when ExploreFields(B) yields the link that triggers the StopAt condition.
Alternative approaches:
-
append the selector spec to allow for a "startWIdth" additional selector in ExploreRecursive. This would essentially say: run this selector till you hit the first ExploreRecursiveEdge, then switch to standard sequence selector. This matches closely to the current compiled implementation of ExploreRecursive which does suggest some value in the approach. It captures the concept of starting "in the middle" of an iteration.
-
support at stop at condition on all selectors -- this seems like a big change. But also should we have such a thing? maybe we should no?
What
Currently we have a set of functions to go from a selector expressed as IPLD (eg datamodel.Node) to a compiled selector that we hand to traversal functions.
There are a number of reasons we might want to go the other way. For example, to serialize the state of a traversal in the middle. Or to serialize selectors for the purpose of comparison.
Currently, based on how these selectors are implemented, it's relatively trivial to write a decompile for most of the selectors. However, explore recursive is very tricky. The reason is while traversing intermediate nodes between an ExploreRecursive and an ExploreRecursiveEdge, there is a compiled selector that we can execute (currently just ExploreRecursive), but no obvious decompiled form of it.
Consider this selector chain:
How do we decompile a selector for the point in the traversal when we have followed
ExploreFields(A)but notExploreFields(B)?At first glance, one way to "decompile" this selector would be to simply defer the insertion of
ExploreRecursiveuntil the firstExploreRecursiveEdgeand then put theExploreRecursivein at that point with a decremented limit (if we're not doing RecursionLimitNone). So we get something like:The problem here is the
StopAtcondition on ExploreRecursive.If
ExploreFields(B)when applied to the underlying data yields the linkQmz...that triggers theStopAtcondition, then the approach above no longer works:is not the correct selector, as it doesn't stop when
ExploreFields(B)yields the link that triggers theStopAtcondition.Alternative approaches:
append the selector spec to allow for a "startWIdth" additional selector in ExploreRecursive. This would essentially say: run this selector till you hit the first ExploreRecursiveEdge, then switch to standard sequence selector. This matches closely to the current compiled implementation of ExploreRecursive which does suggest some value in the approach. It captures the concept of starting "in the middle" of an iteration.
support at stop at condition on all selectors -- this seems like a big change. But also should we have such a thing? maybe we should no?