While in #1 we envisioned the Treecle class as a way to reuse a Treecle config, I think it may be useful to allow optionally binding it to a specific tree too. There are use cases like Vastly's where Treecle will be reused with the same settings across multiple trees, but also use cases where Treecle will be used on the same tree repeatedly (e.g. an app that operates a single data tree).
This has several ergonomics benefits over simply passing nodes of the same tree to a Treecle instance repeatedly:
Being able to omit arguments when the node to be passed is the tree root (e.g. for walk(), map(), transform(), find())
For all methods that require parent pointers, we can simply add them to the tree if they don't exist, rather than having to produce an error.
So I’m thinking we ideally want to allow the following:
new Treecle(root, config);
new Treecle(root, otherTreecle); // copy config from another treecle and use it on a new tree
new Treecle(otherTreecle); // pass in both root and config from another treecle, essentially clone
new Treecle(root); // use default config
The latter introduces a bit of a catch-22: how can we distinguish between new Treecle(config) and new Treecle(root)?
It's not impossible, just adds some complication. E.g. I can think of two ways to do it:
only copy any properties from the argument that are present in defaults instead of indiscriminately copying them all via Object.assign() (which is probably good practice in general). The downside is that in a situation where nodes can have properties with the same name as config settings, this will break.
Another way would be to call defaults.isNode() on the argument, and edit the default isNode() to never return true for config objects. Can't think of any way to reliably tell between nodes and config objects in the general case without making the same assumption as above though (that there are no name conflicts).
I'm inclined to simply postpone new Treecle(root) since there's no robust way to implement it, and it adds complexity for a rather small benefit to authors.
While in #1 we envisioned the Treecle class as a way to reuse a Treecle config, I think it may be useful to allow optionally binding it to a specific tree too. There are use cases like Vastly's where Treecle will be reused with the same settings across multiple trees, but also use cases where Treecle will be used on the same tree repeatedly (e.g. an app that operates a single data tree).
This has several ergonomics benefits over simply passing nodes of the same tree to a Treecle instance repeatedly:
walk()
,map()
,transform()
,find()
)So I’m thinking we ideally want to allow the following:
The latter introduces a bit of a catch-22: how can we distinguish between
new Treecle(config)
andnew Treecle(root)
? It's not impossible, just adds some complication. E.g. I can think of two ways to do it:defaults
instead of indiscriminately copying them all viaObject.assign()
(which is probably good practice in general). The downside is that in a situation where nodes can have properties with the same name as config settings, this will break.defaults.isNode()
on the argument, and edit the defaultisNode()
to never return true for config objects. Can't think of any way to reliably tell between nodes and config objects in the general case without making the same assumption as above though (that there are no name conflicts).I'm inclined to simply postpone
new Treecle(root)
since there's no robust way to implement it, and it adds complexity for a rather small benefit to authors.