export class View {
  constructor(sequence, low, high) {
    const substrate = Array(high - low);
    if (sequence instanceof View) {
      substrate.original = sequence.original;
      substrate.low = sequence.low + low;
      substrate.high = sequence.low + high;
    } else {
      substrate.original = sequence;
      substrate.low = low;
      substrate.high = high;
    }
    const toOriginalIndex = (property) => {
      if (typeof property === 'string' && /^\d+$/.test(property)) {
        const result = substrate.low + Number(property);
        if (result < substrate.high) {
          return result;
        }
      }
      return undefined;
    };
    return new Proxy(substrate, {
      get(target, property, receiver) {
        const originalIndex = toOriginalIndex(property);
        if (originalIndex !== undefined) {
          return target.original[originalIndex];
        }
        return Reflect.get(target, property, receiver);
      },
      set(target, property, value, receiver) {
        const originalIndex = toOriginalIndex(property);
        if (originalIndex !== undefined) {
          target.original[originalIndex] = value;
          return true;
        }
        return Reflect.set(target, property, value, receiver);
      },
    });
  }
}