{"version":3,"file":"CircularVector.mjs","sources":["../../../src/vector/CircularVector.ts"],"sourcesContent":["import { FunctionalVector } from './FunctionalVector';\n\ninterface CircularOptions<T> {\n  buffer?: T[];\n  append?: 'head' | 'tail';\n  capacity?: number;\n}\n\n/**\n * Circular vector uses a single buffer to capture a stream of values\n * overwriting the oldest value on add.\n *\n * This supports adding to the 'head' or 'tail' and will grow the buffer\n * to match a configured capacity.\n *\n * @public\n * @deprecated use a simple Arrays\n */\nexport class CircularVector<T = unknown> extends FunctionalVector<T> {\n  private buffer: T[];\n  private index: number;\n  private capacity: number;\n  private tail: boolean;\n\n  constructor(options: CircularOptions<T>) {\n    super();\n\n    this.buffer = options.buffer || [];\n    this.capacity = this.buffer.length;\n    this.tail = 'head' !== options.append;\n    this.index = 0;\n\n    this.add = this.getAddFunction();\n    if (options.capacity) {\n      this.setCapacity(options.capacity);\n    }\n    return new Proxy(this, {\n      get(target: CircularVector<T>, property: string, receiver: CircularVector<T>) {\n        if (typeof property !== 'symbol') {\n          const idx = +property;\n          if (String(idx) === property) {\n            return target.get(idx);\n          }\n        }\n        return Reflect.get(target, property, receiver);\n      },\n      set(target: CircularVector<T>, property: string, value: T, receiver: CircularVector<T>) {\n        if (typeof property !== 'symbol') {\n          const idx = +property;\n          if (String(idx) === property) {\n            target.set(idx, value);\n            return true;\n          }\n        }\n        return Reflect.set(target, property, value, receiver);\n      },\n    });\n  }\n\n  /**\n   * This gets the appropriate add function depending on the buffer state:\n   *  * head vs tail\n   *  * growing buffer vs overwriting values\n   */\n  private getAddFunction(): (value: T) => void {\n    // When we are not at capacity, it should actually modify the buffer\n    if (this.capacity > this.buffer.length) {\n      if (this.tail) {\n        return (value: T) => {\n          this.buffer.push(value);\n          if (this.buffer.length >= this.capacity) {\n            this.add = this.getAddFunction();\n          }\n        };\n      } else {\n        return (value: T) => {\n          this.buffer.unshift(value);\n          if (this.buffer.length >= this.capacity) {\n            this.add = this.getAddFunction();\n          }\n        };\n      }\n    }\n\n    if (this.tail) {\n      return (value: T) => {\n        this.buffer[this.index] = value;\n        this.index = (this.index + 1) % this.buffer.length;\n      };\n    }\n\n    // Append values to the head\n    return (value: T) => {\n      let idx = this.index - 1;\n      if (idx < 0) {\n        idx = this.buffer.length - 1;\n      }\n      this.buffer[idx] = value;\n      this.index = idx;\n    };\n  }\n\n  setCapacity(v: number) {\n    if (this.capacity === v) {\n      return;\n    }\n    // Make a copy so it is in order and new additions can be at the head or tail\n    const copy = this.toArray();\n    if (v > this.length) {\n      this.buffer = copy;\n    } else if (v < this.capacity) {\n      // Shrink the buffer\n      const delta = this.length - v;\n      if (this.tail) {\n        this.buffer = copy.slice(delta, copy.length); // Keep last items\n      } else {\n        this.buffer = copy.slice(0, copy.length - delta); // Keep first items\n      }\n    }\n    this.capacity = v;\n    this.index = 0;\n    this.add = this.getAddFunction();\n  }\n\n  setAppendMode(mode: 'head' | 'tail') {\n    const tail = 'head' !== mode;\n    if (tail !== this.tail) {\n      this.buffer = this.toArray().reverse();\n      this.index = 0;\n      this.tail = tail;\n      this.add = this.getAddFunction();\n    }\n  }\n\n  reverse() {\n    return this.buffer.reverse();\n  }\n\n  get(index: number) {\n    return this.buffer[(index + this.index) % this.buffer.length];\n  }\n\n  set(index: number, value: T) {\n    this.buffer[(index + this.index) % this.buffer.length] = value;\n  }\n\n  get length() {\n    return this.buffer.length;\n  }\n}\n"],"names":[],"mappings":"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"}