public async Task <IPropertyNodeProxy> ProxyPropertyNodeAsync(string name, bool watch = false, string parentPath = default)
        {
            var path = NodeProxy.JoinPath(parentPath, name);
            var node = new PropertyNodeProxy(this, name, path);

            if (watch)
            {
                var watcher = new NodeProxy.NodeWatcher(node);
                await node.WatchedByAsync(watcher).ConfigureAwait(false);
            }
            return(node);
        }
        public async Task <IDataNodeProxy <T> > ProxyJsonNodeAsync <T>(string name, bool watch = false, string parentPath = default) where T : class
        {
            var path = NodeProxy.JoinPath(parentPath, name);
            var node = new JsonNodeProxy <T>(this, name, path);

            if (watch)
            {
                var watcher = new DataNodeProxy <T> .NodeWatcher(node);

                await node.WatchedByAsync(watcher).ConfigureAwait(false);
            }
            return(node);
        }
        public async Task <IDataNodeProxy <T> > ProxyValueNodeAsync <T>(string name, bool watch = false, string parentPath = default)
        {
            var path = NodeProxy.JoinPath(parentPath, name);
            DataNodeProxy <T> node;

            if (typeof(T) == typeof(string))
            {
                node = new StringNodeProxy(this, name, path) as ValueNodeProxy <T>;
            }
            else
            {
                node = new ValueNodeProxy <T>(this, name, path);
            }
            if (watch)
            {
                var watcher = new DataNodeProxy <T> .NodeWatcher(node);

                await node.WatchedByAsync(watcher).ConfigureAwait(false);
            }
            return(node);
        }