export const domArray = (methods, extra) => {
	if (extra) return domArray(extra)(methods)

	const traps = {
		get(target, prop) {
			if (prop === "length") {
				return target.children.length
			} else if (prop === Symbol.iterator) {
				return function*() {
					for (const child of target.children) {
						yield methods.get.call(child)
					}
				}
			} else if (prop.match?.call(prop, /^[0-9]+$/)) {
				const child = target.children[prop]
				if (child) return methods.get.call(child)
				return child
			} else {
				return Array.prototype[prop]
			}
		},
		set(target, prop, value) {
			if (prop.match?.call(prop, /^[0-9]+$/)) {
				const child = target.children[prop]
				if (child) {
					methods.set.call(child, value)
					return true
				} else {
					for (let i = target.children.length; i < Number(prop); i++) {
						target.appendChild(methods.new(undefined))
					}
					const element = methods.new(value)
					target.appendChild(element)
					if (methods.get.call(element) !== value)
						methods.set.call(element, value)
					return true
				}
			} else if (prop == "length") {
				if (value == target.children.length)
					return true
				else
					return false
			}
		},
		deleteProperty(target, prop) {
			if (prop.match?.call(prop, /^[0-9]+$/)) {
				const child = target.children[prop]
				if (child) child.remove()
				return true
			}
		},
		has(target, prop) {
			return (prop === Symbol.iterator) || (prop in target.children) || (prop in Array.prototype)
		}
	}

	return element => {
		if (!(element instanceof Element)) throw(new Error("Creating domArray on non-element"))
		return new Proxy(element, traps)
	}
}

export const meta = (element=document.head) => new Proxy(element, {
	get: (target, name) => target.querySelector(`meta[name="${name}"]`)?.content,
	set: (target, name, value) => {
		let meta = target.querySelector(`meta[name="${name}"]`)
		if (!meta) {
			meta = document.createElement("meta")
			meta.name = name
			target.append(meta)
		}
		meta.content = value
	}
})