"use strict";
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __await = function(promise, isYieldStar) {
  this[0] = promise;
  this[1] = isYieldStar;
};
var __asyncGenerator = (__this, __arguments, generator) => {
  var resume = (k, v, yes, no) => {
    try {
      var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done;
      Promise.resolve(isAwait ? v[0] : v).then((y) => isAwait ? resume(k === "return" ? k : "next", v[1] ? { done: y.done, value: y.value } : y, yes, no) : yes({ value: y, done })).catch((e) => resume("throw", e, yes, no));
    } catch (e) {
      no(e);
    }
  }, method = (k) => it[k] = (x) => new Promise((yes, no) => resume(k, x, yes, no)), it = {};
  return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it;
};
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);

// src/index.ts
var src_exports = {};
__export(src_exports, {
  Sandbox: () => Sandbox,
  default: () => src_default
});
module.exports = __toCommonJS(src_exports);
__reExport(src_exports, require("e2b"), module.exports);

// src/sandbox.ts
var import_e2b3 = require("e2b");

// src/messaging.ts
var import_e2b = require("e2b");
async function extractError(res) {
  if (res.ok) {
    return;
  }
  switch (res.status) {
    case 502:
      return new import_e2b.TimeoutError(
        `${await res.text()}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeoutMs' when starting the sandbox or calling '.setTimeout' on the sandbox with the desired timeout.`
      );
    case 404:
      return new import_e2b.NotFoundError(await res.text());
    default:
      return new import_e2b.SandboxError(`${res.status} ${res.statusText}`);
  }
}
var ExecutionError = class {
  constructor(name, value, traceback) {
    this.name = name;
    this.value = value;
    this.traceback = traceback;
  }
};
var Result = class {
  constructor(rawData, isMainResult) {
    this.isMainResult = isMainResult;
    const data = __spreadValues({}, rawData);
    delete data["type"];
    delete data["is_main_result"];
    this.text = data["text"];
    this.html = data["html"];
    this.markdown = data["markdown"];
    this.svg = data["svg"];
    this.png = data["png"];
    this.jpeg = data["jpeg"];
    this.pdf = data["pdf"];
    this.latex = data["latex"];
    this.json = data["json"];
    this.javascript = data["javascript"];
    this.isMainResult = isMainResult;
    this.raw = data;
    this.data = data["data"];
    this.chart = data["chart"];
    this.extra = {};
    for (const key of Object.keys(data)) {
      if (![
        "plain",
        "html",
        "markdown",
        "svg",
        "png",
        "jpeg",
        "pdf",
        "latex",
        "json",
        "javascript",
        "data",
        "chart",
        "extra",
        "text"
      ].includes(key)) {
        this.extra[key] = data[key];
      }
    }
  }
  /**
   * Returns all the formats available for the result.
   *
   * @returns Array of strings representing the formats available for the result.
   */
  formats() {
    const formats = [];
    if (this.html) {
      formats.push("html");
    }
    if (this.markdown) {
      formats.push("markdown");
    }
    if (this.svg) {
      formats.push("svg");
    }
    if (this.png) {
      formats.push("png");
    }
    if (this.jpeg) {
      formats.push("jpeg");
    }
    if (this.pdf) {
      formats.push("pdf");
    }
    if (this.latex) {
      formats.push("latex");
    }
    if (this.json) {
      formats.push("json");
    }
    if (this.javascript) {
      formats.push("javascript");
    }
    if (this.data) {
      formats.push("data");
    }
    for (const key of Object.keys(this.extra)) {
      formats.push(key);
    }
    return formats;
  }
  /**
   * Returns the serializable representation of the result.
   */
  toJSON() {
    return __spreadValues({
      text: this.text,
      html: this.html,
      markdown: this.markdown,
      svg: this.svg,
      png: this.png,
      jpeg: this.jpeg,
      pdf: this.pdf,
      latex: this.latex,
      json: this.json,
      javascript: this.javascript
    }, Object.keys(this.extra).length > 0 ? { extra: this.extra } : {});
  }
};
var Execution = class {
  constructor(results = [], logs = { stdout: [], stderr: [] }, error, executionCount) {
    this.results = results;
    this.logs = logs;
    this.error = error;
    this.executionCount = executionCount;
  }
  /**
   * Returns the text representation of the main result of the cell.
   */
  get text() {
    for (const data of this.results) {
      if (data.isMainResult) {
        return data.text;
      }
    }
  }
  /**
   * Returns the serializable representation of the execution result.
   */
  toJSON() {
    return {
      results: this.results,
      logs: this.logs,
      error: this.error
    };
  }
};
async function parseOutput(execution, line, onStdout, onStderr, onResult, onError) {
  const msg = JSON.parse(line);
  switch (msg.type) {
    case "result":
      const result = new Result(
        __spreadProps(__spreadValues({}, msg), { type: void 0, is_main_result: void 0 }),
        msg.is_main_result
      );
      execution.results.push(result);
      if (onResult) {
        await onResult(result);
      }
      break;
    case "stdout":
      execution.logs.stdout.push(msg.text);
      if (onStdout) {
        await onStdout({
          error: false,
          line: msg.text,
          timestamp: (/* @__PURE__ */ new Date()).getTime() * 1e3
        });
      }
      break;
    case "stderr":
      execution.logs.stderr.push(msg.text);
      if (onStderr) {
        await onStderr({
          error: true,
          line: msg.text,
          timestamp: (/* @__PURE__ */ new Date()).getTime() * 1e3
        });
      }
      break;
    case "error":
      execution.error = new ExecutionError(msg.name, msg.value, msg.traceback);
      if (onError) {
        await onError(execution.error);
      }
      break;
    case "number_of_executions":
      execution.executionCount = msg.execution_count;
      break;
  }
}

// src/utils.ts
var import_e2b2 = require("e2b");
function formatRequestTimeoutError(error) {
  if (error instanceof Error && error.name === "AbortError") {
    return new import_e2b2.TimeoutError("Request timed out \u2014 the 'requestTimeoutMs' option can be used to increase this timeout");
  }
  return error;
}
function formatExecutionTimeoutError(error) {
  if (error instanceof Error && error.name === "AbortError") {
    return new import_e2b2.TimeoutError("Execution timed out \u2014 the 'timeoutMs' option can be used to increase this timeout");
  }
  return error;
}
function readLines(stream) {
  return __asyncGenerator(this, null, function* () {
    const reader = stream.getReader();
    let buffer = "";
    try {
      while (true) {
        const { done, value } = yield new __await(reader.read());
        if (value !== void 0) {
          buffer += new TextDecoder().decode(value);
        }
        if (done) {
          if (buffer.length > 0) {
            yield buffer;
          }
          break;
        }
        let newlineIdx = -1;
        do {
          newlineIdx = buffer.indexOf("\n");
          if (newlineIdx !== -1) {
            yield buffer.slice(0, newlineIdx);
            buffer = buffer.slice(newlineIdx + 1);
          }
        } while (newlineIdx !== -1);
      }
    } finally {
      reader.releaseLock();
    }
  });
}

// src/consts.ts
var DEFAULT_TIMEOUT_MS = 6e4;
var JUPYTER_PORT = 49999;

// src/sandbox.ts
var Sandbox = class extends import_e2b3.Sandbox {
  async runCode(code, opts) {
    var _a, _b, _c;
    if ((opts == null ? void 0 : opts.context) && (opts == null ? void 0 : opts.language)) {
      throw new import_e2b3.InvalidArgumentError("You can provide context or language, but not both at the same time.");
    }
    const controller = new AbortController();
    const requestTimeout = (_a = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a : this.connectionConfig.requestTimeoutMs;
    const reqTimer = requestTimeout ? setTimeout(() => {
      controller.abort();
    }, requestTimeout) : void 0;
    try {
      const res = await fetch(`${this.jupyterUrl}/execute`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          code,
          context_id: (_b = opts == null ? void 0 : opts.context) == null ? void 0 : _b.id,
          language: opts == null ? void 0 : opts.language,
          env_vars: opts == null ? void 0 : opts.envs
        }),
        signal: controller.signal,
        keepalive: true
      });
      const error2 = await extractError(res);
      if (error2) {
        throw error2;
      }
      if (!res.body) {
        throw new Error(`Not response body: ${res.statusText} ${await (res == null ? void 0 : res.text())}`);
      }
      clearTimeout(reqTimer);
      const bodyTimeout = (_c = opts == null ? void 0 : opts.timeoutMs) != null ? _c : DEFAULT_TIMEOUT_MS;
      const bodyTimer = bodyTimeout ? setTimeout(() => {
        controller.abort();
      }, bodyTimeout) : void 0;
      const execution = new Execution();
      try {
        try {
          for (var iter = __forAwait(readLines(res.body)), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
            const chunk = temp.value;
            await parseOutput(execution, chunk, opts == null ? void 0 : opts.onStdout, opts == null ? void 0 : opts.onStderr, opts == null ? void 0 : opts.onResult, opts == null ? void 0 : opts.onError);
          }
        } catch (temp) {
          error = [temp];
        } finally {
          try {
            more && (temp = iter.return) && await temp.call(iter);
          } finally {
            if (error)
              throw error[0];
          }
        }
      } catch (error3) {
        throw formatExecutionTimeoutError(error3);
      } finally {
        clearTimeout(bodyTimer);
      }
      return execution;
    } catch (error2) {
      throw formatRequestTimeoutError(error2);
    }
  }
  /**
   * Creates a new context to run code in.
   *
   * @param opts options for creating the context.
   * 
   * @returns context object.
   */
  async createCodeContext(opts) {
    try {
      const res = await fetch(`${this.jupyterUrl}/contexts`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          language: opts == null ? void 0 : opts.language,
          cwd: opts == null ? void 0 : opts.cwd
        }),
        keepalive: true,
        signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
      });
      const error = await extractError(res);
      if (error) {
        throw error;
      }
      return await res.json();
    } catch (error) {
      throw formatRequestTimeoutError(error);
    }
  }
  get jupyterUrl() {
    return `${this.connectionConfig.debug ? "http" : "https"}://${this.getHost(JUPYTER_PORT)}`;
  }
};
Sandbox.defaultTemplate = "code-interpreter-v1";

// src/index.ts
var src_default = Sandbox;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Sandbox,
  ...require("e2b")
});
//# sourceMappingURL=index.js.map