−25%

la planurile Windows anuale, până pe 31 oct. Vezi planurile

EQVPS
Începe

SDK de sandbox TypeScript în 5 minute: de la npm i @eqvps/sdk la prima rulare

Instalează @eqvps/sdk, pornește un sandbox Firecracker din Node.js, Deno sau Bun, rulează în el cod Python, Node și shell, mută fișiere și urmărește în timp real o sarcină lungă. Șase pași, cu fiecare linie de cod.

Ghidul ăsta pornește un sandbox din JavaScript sau TypeScript. Vei porni o microVM Firecracker izolată, vei rula cod în trei limbaje, vei muta fișiere și vei urmări ieșirea unei sarcini lungi. Fiecare pas e un fragment scurt.

Îți trebuie Node.js 18+ (sau Deno, sau Bun) și un cont EQVPS.

1. Obține un token

SDK-ul se autentifică cu un token de cont obișnuit. Conectarea contului arată cum obții unul din dashboard, din API sau din serverul MCP.

export EQVPS_API_KEY="your-token"

Un cont nou, fără sold, primește $1 credit de sandbox prima dată când creează un sandbox. Ajunge pentru ghidul ăsta de multe ori.

2. Instalează SDK-ul

npm i @eqvps/sdk

Exemplele folosesc module ES și await la nivel superior. Salvează-le ca fișiere .mjs sau ca .ts și rulează-le cu npx tsx.

3. Pornește un sandbox și rulează cod

import { Sandbox } from "@eqvps/sdk";

await Sandbox.with({ tariff: "small" }, async (sb) => {
  console.log(sb.id);
  const r = await sb.run("import platform; print(platform.python_version())");
  console.log(r.exit_code, r.stdout);
});

Ieșirea e id-ul sandboxului (sb_ și încă 24 de caractere), apoi 0 3.12.x. Sandbox.with șterge sandboxul când se termină callbackul, chiar și dacă aruncă o excepție.

Limbajul implicit e Python. Celelalte două sunt la o opțiune distanță:

await Sandbox.with({}, async (sb) => {
  const js = await sb.run("console.log(process.version)", { language: "node" });
  const sh = await sb.run("uname -r && nproc", { language: "bash" });
  console.log(js.stdout, sh.stdout);
});

Un script care eșuează nu aruncă excepție. Verifică r.ok, care e true când exit_code e 0 și comanda nu a depășit timpul.

4. Comenzi shell și pachete

exec primește un șir shell sau un tablou argv. Sandboxul are acces la internet, deci instalările npm și pip merg:

await Sandbox.with({ tariff: "small" }, async (sb) => {
  await sb.exec("mkdir -p /root/app && cd /root/app && npm init -y && npm i lodash", { timeout: 55 });
  const r = await sb.exec(["node", "-e", "console.log(require('/root/app/node_modules/lodash').VERSION)"]);
  console.log(r.stdout);
});

Un apel sincron poate rula cel mult 55 de secunde. Orice e mai lung merge într-o sarcină de fundal (pasul 6).

5. Fișiere

await Sandbox.with({}, async (sb) => {
  await sb.upload("/root/input.json", JSON.stringify({ values: [3, 5, 8] }));
  await sb.run("import json; d = json.load(open('/root/input.json')); open('/root/out.txt', 'w').write(str(sum(d['values'])))");
  console.log(await sb.downloadText("/root/out.txt"));   // 16
});

upload primește un șir sau un Uint8Array. download returnează un Uint8Array, downloadText un șir. Un transfer e limitat la 5 MB.

6. Sarcini lungi, cu ieșire în timp real

await Sandbox.with({ tariff: "standard" }, async (sb) => {
  const task = await sb.exec("for i in 1 2 3 4 5; do echo step $i; sleep 20; done", { background: true });
  const res = await task.wait({ onOutput: (out) => process.stdout.write(out) });
  console.log(res.state, res.exit_code);   // done 0
});

Sarcina returnează imediat și nu are limita de 55 de secunde. wait verifică implicit la fiecare 2 secunde (pollIntervalMs schimbă asta). task.kill() o oprește; sb.task(id) se reconectează la ea din alt proces.

Erori

import { Sandbox, InsufficientBalanceError, RateLimitError } from "@eqvps/sdk";

try {
  await Sandbox.with({}, async (sb) => console.log((await sb.run("print(1)")).stdout));
} catch (e) {
  if (e instanceof InsufficientBalanceError) console.log("Top up the balance");
  else if (e instanceof RateLimitError) console.log("Busy, retry in", e.retryAfter);
  else throw e;
}

SDK-ul reîncearcă singur 429 și 503, de până la trei ori, când serverul trimite Retry-After. Cel mai frecvent 429 vine din rularea a mai mult de două comenzi deodată pe un cont. Fiecare clasă e în referința SDK.

Cât costă ghidul ăsta

Fiecare exemplu a trăit câteva secunde și a fost facturat la minimul de 60 de secunde: $0.00055 pe small, $0.0011 pe standard. Sarcina de la pasul 6 a rulat în jur de 100 de secunde pe standard, aproximativ $0.002. Totul la un loc e mult sub un cent. Lista completă de prețuri e în limitele și facturarea sandboxurilor.

Pașii următori

Întrebări frecvente

Ce runtime-uri suportă @eqvps/sdk?

Node.js 18 și mai nou, Deno și Bun. Nu are dependențe și folosește fetch-ul integrat, deci merge și în browser, dar nu pune tokenul contului în codul de front-end.

Poate sandboxul să ruleze Python dacă aplicația mea e în TypeScript?

Da. Limbajul aplicației tale și limbajul codului din sandbox sunt separate. run acceptă limbajul python, node sau bash, iar exec rulează orice comandă shell.

Cum mă asigur că sandboxul e șters?

Folosește Sandbox.with(options, fn), care șterge sandboxul când fn se termină sau aruncă o excepție. Cu TypeScript 5.2 sau mai nou poți scrie și await using sb = await Sandbox.create().

Ce returnează run când codul eșuează?

Un ExecResult cu exit_code diferit de zero și eroarea în stderr. Nu aruncă excepție. Excepțiile sunt doar pentru erorile de API, cum ar fi un token invalid sau un sold gol.

Comentarii

Încă nu există comentarii. Fii primul.

Lasă un comentariu

Comentariile sunt moderate înainte să apară.