import { proxy } from '../vanilla'
type InternalProxySet<T> = Set<T> & { data: T[] toJSON: object}
export function proxySet<T>(initialValues?: Iterable<T> | null): Set<T> { const set: InternalProxySet<T> = proxy({ data: Array.from(new Set(initialValues)), has(value) { return this.data.indexOf(value) !== -1 }, add(value) { let hasProxy = false if (typeof value === 'object' && value !== null) { hasProxy = this.data.indexOf(proxy(value as T & object)) !== -1 } if (this.data.indexOf(value) === -1 && !hasProxy) { this.data.push(value) } return this }, delete(value) { const index = this.data.indexOf(value) if (index === -1) { return false } this.data.splice(index, 1) return true }, clear() { this.data.splice(0) }, get size() { return this.data.length }, forEach(cb) { this.data.forEach((value) => { cb(value, value, this) }) }, get [Symbol.toStringTag]() { return 'Set' }, toJSON() { return {} }, [Symbol.iterator]() { return this.data[Symbol.iterator]() }, values() { return this.data.values() }, keys() { return this.data.values() }, entries() { return new Set(this.data).entries() }, })
Object.defineProperties(set, { data: { enumerable: false, }, size: { enumerable: false, }, toJSON: { enumerable: false, }, })
Object.seal(set)
return set as Set<T>}