'use strict';

var utils_types_array = require('../../utils/types/array.cjs');
require('crypto');
var utils_interfaces = require('../../utils/interfaces.cjs');
var utils_inheritance = require('../../utils/inheritance.cjs');
require('bs58');
require('multiformats/bases/base58');
require('varint');
require('../../utils/encoding/ss-58.cjs');
var types_generic_withBase = require('./with-base.cjs');
var types_generic_withCatchNull = require('./with-catch-null.cjs');
var types_generic_withEq = require('./with-eq.cjs');
require('../../utils/types/object.cjs');
require('../../utils/types/iterable.cjs');
require('../../utils/types/set.cjs');
require('../../utils/assert.cjs');
require('../../utils/error.cjs');
require('blake2b');
require('../../utils/types/bytes.cjs');
require('../../utils/types/string.cjs');
require('./with-from-json-bytes.cjs');
require('./any-of.cjs');
require('./with-from.cjs');

/**
 * An Array of items where each item is an instance of the associated Class.
 * The array enforces type consistency by converting items to the specified Class
 * during construction, push, and unshift operations. It provides additional utilities
 * for equality checks and difference calculations between arrays.
 */
let TypedArray$1 = class TypedArray extends types_generic_withBase(utils_types_array.ArrayWithoutPrototypeMethods) {
  /**
   * Item class.
   */
  static Class;

  constructor(...items) {
    if (items.length === 1 && typeof items[0] === 'number') {
      super(items[0]);

      return;
    }
    super(items.length);

    for (let idx = 0; idx < items.length; idx++) {
      try {
        this[idx] = utils_interfaces.maybeFrom(this.constructor.Class, items[idx]);
      } catch (error) {
        error.message = `\nFailed to set \`${idx}\` item of \`${this.constructor.name}\`:\n${error}`;

        throw error;
      }
    }
  }

  push(item) {
    return Array.prototype.push.call(
      this,
      utils_interfaces.maybeFrom(this.constructor.Class, item),
    );
  }

  unshift(item) {
    return Array.prototype.unshift.call(
      this,
      utils_interfaces.maybeFrom(this.constructor.Class, item),
    );
  }

  apply(fn) {
    return [...this].map(fn);
  }

  static fromApi(arr) {
    return new this(...utils_types_array.ensureArrayLike(arr, this.name));
  }

  static fromJSON(arr) {
    return new this(...utils_types_array.ensureArrayLike(arr, this.name));
  }

  static from(value) {
    if (value instanceof this) {
      return value;
    } else if (Array.isArray(value)) {
      return this.fromJSON(value);
    } else if (typeof value === 'object') {
      return this.fromApi(value);
    } else {
      return new this(value);
    }
  }

  eq(other) {
    if (this.length !== other.length) {
      return false;
    }

    for (let i = 0; i < this.length; i++) {
      if (!utils_interfaces.maybeEq(this[i], other[i])) {
        return false;
      }
    }

    return true;
  }

  diff(other) {
    return {
      added: this.filter((item) => other.every((curItem) => !utils_interfaces.maybeEq(curItem, item))),
      removed: other.filter((item) => this.every((nextItem) => !utils_interfaces.maybeEq(nextItem, item))),
    };
  }

  toJSON() {
    return [...this].map((item) => (item.toJSON ? item.toJSON() : item));
  }
};

var TypedArray = types_generic_withEq(
  types_generic_withCatchNull(utils_inheritance.withExtendedStaticProperties(['Class'], TypedArray$1)),
);

module.exports = TypedArray;
//# sourceMappingURL=typed-array.cjs.map
