"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var MatterError_exports = {};
__export(MatterError_exports, {
  AbortedError: () => AbortedError,
  CanceledError: () => CanceledError,
  ClosedError: () => ClosedError,
  ImplementationError: () => ImplementationError,
  ImportError: () => ImportError,
  InternalError: () => InternalError,
  MatterAggregateError: () => MatterAggregateError,
  MatterError: () => MatterError,
  MatterFlowError: () => MatterFlowError,
  NoProviderError: () => NoProviderError,
  NotImplementedError: () => NotImplementedError,
  ReadOnlyError: () => ReadOnlyError,
  TimeoutError: () => TimeoutError,
  UnexpectedDataError: () => UnexpectedDataError
});
module.exports = __toCommonJS(MatterError_exports);
var import_NodeJsStyleInspectable = require("#log/NodeJsStyleInspectable.js");
var import_identifier_case = require("#util/identifier-case.js");
var import_Error = require("./util/Error.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
const codes = /* @__PURE__ */ new WeakMap();
class MatterError extends Error {
  /**
   * Convert the error to formatted text.
   *
   * matter.js encodes errors with modern JS features including {@link Error#cause} and {@link AggregateError#errors}
   * subfields.  You can use this function to ensure all error details are presented regardless of environment.
   */
  format(format = "plain", indents = 0) {
    let formatterFor = MatterError.formatterFor;
    if (typeof formatterFor !== "function") {
      formatterFor = MatterError.defaultFormatterFactory;
    }
    let formatter = formatterFor(format);
    if (typeof formatter !== "function") {
      formatter = fallbackFormatter;
    }
    let result = formatter(this, indents);
    if (typeof result !== "string") {
      result = `${result}`;
    }
    return result;
  }
  /**
   * A unique textual identifier for the error.
   */
  get id() {
    return MatterError.idFor(this.constructor);
  }
  /**
   * A unique textual identifier for the error.
   */
  static get id() {
    return MatterError.idFor(this);
  }
  /**
   * Obtain matter.js-style error ID for given error constructor.
   */
  static idFor(type) {
    let id = codes.get(type);
    if (id === void 0) {
      let name = type.name;
      if (name.endsWith("Error")) {
        name = name.substring(0, name.length - 5);
      }
      if (name.startsWith("Matter")) {
        name = name.substring(6);
      }
      id = (0, import_identifier_case.decamelize)(name);
      if (id === "") {
        id = "general";
      }
      codes.set(type, id);
    }
    return id;
  }
  /**
   * Rethrow an error unless it is an instance of this class.
   */
  static accept(error) {
    if (error instanceof this) {
      return;
    }
    throw error;
  }
  /**
   * Rethrow an error if it is an instance of this class.
   */
  static reject(error) {
    if (error instanceof this) {
      throw error;
    }
  }
  /**
   * Replace the message in an error.
   *
   * In addition to setting the message, updates the message in the stack.
   */
  static replaceMessage(error, message) {
    const oldMessage = error.message;
    error.message = message;
    const stack = error.stack?.split("\n");
    const messagePos = stack?.findIndex((line) => {
      if (line.startsWith("Error: ")) {
        line = line.slice(7);
      }
      if (line === oldMessage) {
        return true;
      }
    });
    if (messagePos !== void 0 && messagePos !== -1) {
      stack[messagePos] = message;
      error.stack = stack.join("\n");
    }
  }
  /**
   * The fallback formatter factory.  This produces a limited plaintext formatter.
   */
  static defaultFormatterFactory = () => fallbackFormatter;
  /**
   * The error formatter factory.  The default formatter is replaced by Matter.js in ./Format.ts.
   */
  static formatterFor = MatterError.defaultFormatterFactory;
  // TODO - this is probably correct; MatterAggregateError should be typeof MatterError.  Need to diagnose some test
  // breakage before enabling though
  // static [Symbol.hasInstance](instance: unknown) {
  //     if (instance instanceof MatterAggregateError) {
  //         return true;
  //     }
  //     return Error[Symbol.hasInstance](instance);
  // }
}
class NoProviderError extends MatterError {
}
class InternalError extends MatterError {
}
class NotImplementedError extends InternalError {
}
class MatterFlowError extends MatterError {
}
class UnexpectedDataError extends MatterError {
}
class ImplementationError extends MatterError {
}
class ImportError extends MatterError {
}
class ReadOnlyError extends ImplementationError {
  constructor(message = "This view is read-only") {
    super(message);
  }
}
class MatterAggregateError extends AggregateError {
  constructor(causes, message) {
    causes = [...causes].map(import_Error.errorOf);
    super(causes, message);
  }
  /**
   * A unique textual identifier for the error.
   */
  get id() {
    return MatterError.idFor(this.constructor);
  }
  /**
   * A unique textual identifier for the error.
   */
  static get id() {
    return MatterError.idFor(this);
  }
  /**
   * Add causes without stack traces.
   *
   * This is useful to create a compact representation if all child errors originate externally or from the same
   * logical location as the parent error.
   */
  addStackless(error) {
    error.stack = void 0;
    this.errors.push(error);
  }
  // TODO - see comment on MatterError.  If that one is correct this is incorrect
  static [Symbol.hasInstance](instance) {
    if (instance instanceof MatterError) {
      return true;
    }
    return AggregateError[Symbol.hasInstance](instance);
  }
  /**
   * Wait for all promises to settle and throw an error if any of them reject as MatterAggregateError
   * (or extended class). Promise results are not returned.
   */
  static async allSettled(promises, message = "Errors happened") {
    const results = await Promise.allSettled(promises);
    const errors = results.filter((result) => result.status === "rejected").map((result) => result.reason);
    if (errors.length) {
      throw new this(errors, message);
    }
    return results.map((result) => result.value);
  }
  format = MatterError.prototype.format;
}
function fallbackFormatter(value, indents = 0) {
  if (value === void 0 || value === null) {
    return `${value}`;
  }
  function formatOne(value2, indents2, messagePrefix) {
    const { message, stack, cause, errors } = value2;
    let indent;
    if (typeof indents2 !== "number" || indents2 < 0) {
      indent = "";
    } else {
      indent = "  ".repeat(indents2);
    }
    const buffer = [`${indent}${messagePrefix}${message ?? "(unknown error)"}`];
    if (stack !== void 0 && stack !== null) {
      const frames = stack.toString().split("\n");
      frames.shift();
      buffer.push(...frames.map((f) => `${indent}  ${f.trim()}`));
    }
    if (cause !== void 0) {
      buffer.push(formatOne(cause, indents2, "Caused by: "));
    }
    if (typeof errors?.[Symbol.iterator] === "function") {
      let causeNumber = 0;
      for (const error of errors) {
        buffer.push(formatOne(error, indents2 + 1, `Cause #${causeNumber++}: `));
      }
    }
    return buffer.join("\n");
  }
  return formatOne(value, indents, "");
}
class CanceledError extends MatterError {
  constructor(message = "Operation canceled", options) {
    super(message, options);
  }
}
class TimeoutError extends MatterError {
  constructor(message = "Operation timed out", options) {
    super(message, options);
  }
}
class AbortedError extends CanceledError {
  constructor(message = "Operation aborted", options) {
    super(message, options);
  }
  /**
   * Determine whether a cause signifies abort.
   *
   * We include {@link DOMException} with name "AbortError" which is the standard error thrown if you invoke
   * {@link AbortController#abort} without a cause.
   */
  static is(cause) {
    return cause instanceof AbortedError || cause instanceof DOMException && cause.name === "AbortError";
  }
  /**
   * Accept both {@link AbortedError} and {@link DOMException} with name "AbortError".
   */
  static accept(cause) {
    if (AbortedError.is(cause)) {
      return;
    }
    return super.accept(cause);
  }
}
class ClosedError extends CanceledError {
}
function inspector(depth, options) {
  const formatterFor = MatterError.formatterFor;
  if (typeof formatterFor !== "function") {
    return this;
  }
  const format = formatterFor(options.colors ? "ansi" : "plain");
  if (typeof format !== "function") {
    return this;
  }
  return format(this, depth);
}
(0, import_NodeJsStyleInspectable.NodeJsStyleInspectable)(MatterError.prototype, inspector);
(0, import_NodeJsStyleInspectable.NodeJsStyleInspectable)(MatterAggregateError.prototype, inspector);
Object.defineProperty(MatterAggregateError.prototype, "format", {
  value: MatterError.prototype.format,
  configurable: true,
  writable: true,
  enumerable: false
});
//# sourceMappingURL=MatterError.js.map
