import { entries } from 'izuna' import { Clone } from './clone.js' import { IndexableIterator } from './iter.js' /** * @param {...any} values */ export class Tuple { _values _length get length() { return this._length } constructor(values) { if (values.length > 0) { this._length = values.length values.forEach(this._setEntry.bind(this)) } this._values = values } _setEntry([key, value], index) { if (typeof key !== 'number') { Object.defineProperty(this, key, { get() { return this[index] } }) } this[index] = value } static from(values) { return Object.freeze(new this(entries(values))) } toString() { return `(${this._values.map(([_, v]) => v.toString())})` } clone() { return this[Clone]() } [Clone]() { return Object.freeze(new this.constructor(this._values)) } [Symbol.iterator]() { return new IndexableIterator(this._values.map(([_, v]) => v)) } } export const tuple = Tuple.from