// Boundary Walk - Inorder dfs
var treeToDoublyList = function (root) {
	// recursive helper
	function dfs(node) {
		if (node.left) dfs(node.left)
		pred.right = node
		node.left = pred
		pred = node
		if (node.right) dfs(node.right)
	}

	// Overall
	if (!root) return root

	let fake = new TreeNode('fake'),
		pred = fake

	dfs(root)

	const head = fake.right
	pred.right = head
	head.left = pred

	return head
}

// TreeNode
function TreeNode(val, left, right) {
	this.val = val === undefined ? 0 : val
	this.left = left === undefined ? null : left
	this.right = right === undefined ? null : right
}

Tests:

// tests
const tree = {
	val: 5,
	left: {
		val: 2,
		left: { val: 1, left: null, right: null },
		right: { val: 4, left: { val: 3, left: null, right: null }, right: null },
	},
	right: {
		val: 6,
		left: null,
		right: {
			val: 9,
			left: { val: 8, left: { val: 7, left: null, right: null }, right: null },
			right: { val: 10, left: null, right: null },
		},
	},
}

let head = treeToDoublyList(tree)

const rootVal = head.val
node = head.right
console.log(rootVal)
while (node.val !== rootVal) {
	console.log(node.val)
	node = node.right
}