@arker-ai/sdk 0.5.2 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -0
- package/dist/arker-provider-BNIL8NdM.d.ts +7 -0
- package/dist/arker-provider-DwUib5ZW.d.cts +7 -0
- package/dist/chunk-35IEV6BU.js +286 -0
- package/dist/{chunk-YGZOUXII.js → chunk-7BHPVQNG.js} +232 -24
- package/dist/cli.cjs +587 -172
- package/dist/cli.js +355 -148
- package/dist/common-C5zJ-LkS.d.cts +9 -0
- package/dist/common-C5zJ-LkS.d.ts +9 -0
- package/dist/daytona.cjs +1274 -0
- package/dist/daytona.d.cts +37 -0
- package/dist/daytona.d.ts +37 -0
- package/dist/daytona.js +65 -0
- package/dist/e2b.cjs +1288 -0
- package/dist/e2b.d.cts +29 -0
- package/dist/e2b.d.ts +29 -0
- package/dist/e2b.js +75 -0
- package/dist/index.cjs +242 -24
- package/dist/index.d.cts +132 -108
- package/dist/index.d.ts +132 -108
- package/dist/index.js +1 -1
- package/dist/modal.cjs +1356 -0
- package/dist/modal.d.cts +49 -0
- package/dist/modal.d.ts +49 -0
- package/dist/modal.js +130 -0
- package/package.json +30 -4
|
@@ -121,6 +121,12 @@ var Arker = class {
|
|
|
121
121
|
);
|
|
122
122
|
}
|
|
123
123
|
const sourceOrgId = src.sourceOrgId ?? (src.sourceVmName !== void 0 && GOLDEN_NAMES.has(src.sourceVmName) ? ARKER_ORG_ID : void 0);
|
|
124
|
+
const legacy = src;
|
|
125
|
+
const resources = src.resources ?? (legacy.vcpu_count != null || legacy.memory_mib != null || legacy.disk_mib != null ? {
|
|
126
|
+
vcpu: legacy.vcpu_count ?? null,
|
|
127
|
+
memory_mib: legacy.memory_mib ?? null,
|
|
128
|
+
disk_mib: legacy.disk_mib ?? null
|
|
129
|
+
} : null);
|
|
124
130
|
const body = {
|
|
125
131
|
source_vm_id: src.sourceVmId ?? null,
|
|
126
132
|
source_vm_name: src.sourceVmName ?? null,
|
|
@@ -128,13 +134,10 @@ var Arker = class {
|
|
|
128
134
|
name: src.name ?? null,
|
|
129
135
|
public: src.public ?? null,
|
|
130
136
|
network: src.network ?? null,
|
|
137
|
+
egress: src.egress ?? null,
|
|
131
138
|
disk: src.disk ?? true,
|
|
132
|
-
vcpu_count: src.vcpu_count ?? null,
|
|
133
|
-
memory_mib: src.memory_mib ?? null,
|
|
134
|
-
max_memory_mib: src.max_memory_mib ?? null,
|
|
135
|
-
disk_mib: src.disk_mib ?? null,
|
|
136
139
|
durable: src.durable ?? null,
|
|
137
|
-
|
|
140
|
+
resources
|
|
138
141
|
};
|
|
139
142
|
const useBurst = sourceOrgId === ARKER_ORG_ID && src.sourceVmName !== void 0 && isBurstRef(src.sourceVmName);
|
|
140
143
|
const baseUrl = useBurst && this.burstBaseUrl ? this.burstBaseUrl : this.baseUrl;
|
|
@@ -281,6 +284,10 @@ var Arker = class {
|
|
|
281
284
|
return retryDelay(this.retry, attempt);
|
|
282
285
|
}
|
|
283
286
|
/** @internal */
|
|
287
|
+
_authHeaders() {
|
|
288
|
+
return { authorization: `Bearer ${this.apiKey}` };
|
|
289
|
+
}
|
|
290
|
+
/** @internal */
|
|
284
291
|
_baseUrlFor(ref) {
|
|
285
292
|
if (isBurstRef(ref) && this.burstBaseUrl) return this.burstBaseUrl;
|
|
286
293
|
return this.baseUrl;
|
|
@@ -315,7 +322,6 @@ var VM = class _VM {
|
|
|
315
322
|
root_source_vm_name;
|
|
316
323
|
worker_id;
|
|
317
324
|
sessions;
|
|
318
|
-
tunnels;
|
|
319
325
|
constructor(client, vmId, baseUrl = client._baseUrlFor(vmId), data) {
|
|
320
326
|
this._client = client;
|
|
321
327
|
this.id = vmId;
|
|
@@ -438,8 +444,25 @@ var VM = class _VM {
|
|
|
438
444
|
}
|
|
439
445
|
throw new ArkerError(lastError?.code ?? "internal", lastError?.message ?? "write failed", 200);
|
|
440
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* Update this VM's resource allocation and/or network settings via
|
|
449
|
+
* `PATCH /v1/vms/{id}`. Returns the updated `Vm`.
|
|
450
|
+
*
|
|
451
|
+
* Accepts either a `PatchVmRequest` (`{ resources, network }`) or, for
|
|
452
|
+
* convenience, flat resource fields (`{ vcpu, memory_mib, disk_mib }`)
|
|
453
|
+
* which are folded into `resources`.
|
|
454
|
+
*/
|
|
441
455
|
async resize(request) {
|
|
442
|
-
|
|
456
|
+
const r = request;
|
|
457
|
+
const body = r.resources !== void 0 || r.vcpu === void 0 && r.memory_mib === void 0 && r.disk_mib === void 0 ? { resources: r.resources ?? null, network: r.network ?? null } : {
|
|
458
|
+
resources: {
|
|
459
|
+
vcpu: r.vcpu ?? null,
|
|
460
|
+
memory_mib: r.memory_mib ?? null,
|
|
461
|
+
disk_mib: r.disk_mib ?? null
|
|
462
|
+
},
|
|
463
|
+
network: r.network ?? null
|
|
464
|
+
};
|
|
465
|
+
return this._client._request("PATCH", vmPath(this.id), body, this.baseUrl);
|
|
443
466
|
}
|
|
444
467
|
async delete() {
|
|
445
468
|
return this._client._request("DELETE", vmPath(this.id), void 0, this.baseUrl);
|
|
@@ -495,22 +518,30 @@ var VM = class _VM {
|
|
|
495
518
|
async deleteSession(sessionId) {
|
|
496
519
|
return this._client._request("DELETE", `${vmPath(this.id)}/sessions/${pathSegment(sessionId)}`, void 0, this.baseUrl);
|
|
497
520
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
521
|
+
async connectPty(options = {}) {
|
|
522
|
+
const sessionId = options.sessionId ?? sessionIdFrom(await this.createSession());
|
|
523
|
+
const useTicket = options.useTicket ?? !isNodeRuntime();
|
|
524
|
+
const params = {
|
|
525
|
+
cols: options.cols,
|
|
526
|
+
rows: options.rows,
|
|
527
|
+
command: options.command,
|
|
528
|
+
persist: options.persist,
|
|
529
|
+
cancel_ttl_secs: options.cancelTtlSecs && options.cancelTtlSecs > 0 ? Math.floor(options.cancelTtlSecs) : void 0
|
|
530
|
+
};
|
|
531
|
+
let ticket;
|
|
532
|
+
if (useTicket) {
|
|
533
|
+
const response = await this._client._request(
|
|
534
|
+
"POST",
|
|
535
|
+
`${vmPath(this.id)}/sessions/${pathSegment(sessionId)}/pty-ticket`,
|
|
536
|
+
{},
|
|
537
|
+
this.baseUrl
|
|
538
|
+
);
|
|
539
|
+
ticket = response.ticket;
|
|
540
|
+
}
|
|
541
|
+
const url = buildPtyWebSocketUrl(this.baseUrl, this.id, sessionId, { ...params, ticket });
|
|
542
|
+
const factory = options.webSocketFactory ?? (useTicket ? browserPtyWebSocketFactory : nodePtyWebSocketFactory);
|
|
543
|
+
const socket = await factory(url, useTicket ? {} : { headers: this._client._authHeaders() });
|
|
544
|
+
return new PtyConnectionImpl(sessionId, socket);
|
|
514
545
|
}
|
|
515
546
|
};
|
|
516
547
|
function buildQuery(path, params) {
|
|
@@ -522,6 +553,176 @@ function buildQuery(path, params) {
|
|
|
522
553
|
const qs = usp.toString();
|
|
523
554
|
return qs ? `${path}?${qs}` : path;
|
|
524
555
|
}
|
|
556
|
+
function buildPtyWebSocketUrl(baseUrl, vmId, sessionId, params) {
|
|
557
|
+
const url = new URL(`${normalizeBaseUrl(baseUrl)}${vmPath(vmId)}/sessions/${pathSegment(sessionId)}/pty`);
|
|
558
|
+
if (url.protocol === "https:") url.protocol = "wss:";
|
|
559
|
+
else if (url.protocol === "http:") url.protocol = "ws:";
|
|
560
|
+
else throw new Error(`unsupported PTY WebSocket protocol: ${url.protocol}`);
|
|
561
|
+
for (const [key, value] of Object.entries(params)) {
|
|
562
|
+
if (value === void 0 || value === null) continue;
|
|
563
|
+
url.searchParams.set(key, String(value));
|
|
564
|
+
}
|
|
565
|
+
return url.toString();
|
|
566
|
+
}
|
|
567
|
+
function sessionIdFrom(session) {
|
|
568
|
+
const id = session.session_id ?? session.id;
|
|
569
|
+
if (!id) throw new ArkerError("internal", "createSession response missing session_id", 200);
|
|
570
|
+
return id;
|
|
571
|
+
}
|
|
572
|
+
function isNodeRuntime() {
|
|
573
|
+
return typeof process !== "undefined" && Boolean(process.versions?.node);
|
|
574
|
+
}
|
|
575
|
+
async function nodePtyWebSocketFactory(url, init) {
|
|
576
|
+
const ws = await import("ws");
|
|
577
|
+
return new ws.default(url, { headers: init.headers });
|
|
578
|
+
}
|
|
579
|
+
function browserPtyWebSocketFactory(url) {
|
|
580
|
+
if (typeof globalThis.WebSocket !== "function") {
|
|
581
|
+
throw new Error("WebSocket is not available in this runtime");
|
|
582
|
+
}
|
|
583
|
+
return new globalThis.WebSocket(url);
|
|
584
|
+
}
|
|
585
|
+
var PtyConnectionImpl = class {
|
|
586
|
+
constructor(sessionId, socket) {
|
|
587
|
+
this.sessionId = sessionId;
|
|
588
|
+
this.socket = socket;
|
|
589
|
+
try {
|
|
590
|
+
socket.binaryType = "arraybuffer";
|
|
591
|
+
} catch {
|
|
592
|
+
}
|
|
593
|
+
this.ready = waitForSocketOpen(socket);
|
|
594
|
+
addSocketListener(socket, "message", (event) => {
|
|
595
|
+
const data = messageData(event);
|
|
596
|
+
if (data !== void 0) this.emitData(bytesFromMessageData(data));
|
|
597
|
+
});
|
|
598
|
+
addSocketListener(socket, "close", (event) => this.emitClose(closeEvent(event)));
|
|
599
|
+
addSocketListener(socket, "error", (event) => this.emitError(event));
|
|
600
|
+
}
|
|
601
|
+
sessionId;
|
|
602
|
+
socket;
|
|
603
|
+
ready;
|
|
604
|
+
dataListeners = /* @__PURE__ */ new Set();
|
|
605
|
+
closeListeners = /* @__PURE__ */ new Set();
|
|
606
|
+
errorListeners = /* @__PURE__ */ new Set();
|
|
607
|
+
onData(listener) {
|
|
608
|
+
this.dataListeners.add(listener);
|
|
609
|
+
return () => this.dataListeners.delete(listener);
|
|
610
|
+
}
|
|
611
|
+
onClose(listener) {
|
|
612
|
+
this.closeListeners.add(listener);
|
|
613
|
+
return () => this.closeListeners.delete(listener);
|
|
614
|
+
}
|
|
615
|
+
onError(listener) {
|
|
616
|
+
this.errorListeners.add(listener);
|
|
617
|
+
return () => this.errorListeners.delete(listener);
|
|
618
|
+
}
|
|
619
|
+
send(data) {
|
|
620
|
+
this.socket.send(ptyInputBytes(data));
|
|
621
|
+
}
|
|
622
|
+
resize(cols, rows) {
|
|
623
|
+
this.socket.send(JSON.stringify({ type: "resize", cols: clampPtyDimension(cols), rows: clampPtyDimension(rows) }));
|
|
624
|
+
}
|
|
625
|
+
kill() {
|
|
626
|
+
this.socket.send(JSON.stringify({ type: "kill" }));
|
|
627
|
+
}
|
|
628
|
+
close(code, reason) {
|
|
629
|
+
this.socket.close(code, reason);
|
|
630
|
+
}
|
|
631
|
+
emitData(data) {
|
|
632
|
+
for (const listener of this.dataListeners) listener(data);
|
|
633
|
+
}
|
|
634
|
+
emitClose(event) {
|
|
635
|
+
for (const listener of this.closeListeners) listener(event);
|
|
636
|
+
}
|
|
637
|
+
emitError(error) {
|
|
638
|
+
for (const listener of this.errorListeners) listener(error);
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
function waitForSocketOpen(socket) {
|
|
642
|
+
if (socket.readyState === 1) return Promise.resolve();
|
|
643
|
+
return new Promise((resolve, reject) => {
|
|
644
|
+
let removeOpen;
|
|
645
|
+
let removeError;
|
|
646
|
+
let removeClose;
|
|
647
|
+
const cleanup = () => {
|
|
648
|
+
removeOpen?.();
|
|
649
|
+
removeError?.();
|
|
650
|
+
removeClose?.();
|
|
651
|
+
};
|
|
652
|
+
removeOpen = addSocketListener(socket, "open", () => {
|
|
653
|
+
cleanup();
|
|
654
|
+
resolve();
|
|
655
|
+
});
|
|
656
|
+
removeError = addSocketListener(socket, "error", (event) => {
|
|
657
|
+
cleanup();
|
|
658
|
+
reject(event instanceof Error ? event : new Error("PTY WebSocket failed to open"));
|
|
659
|
+
});
|
|
660
|
+
removeClose = addSocketListener(socket, "close", (event) => {
|
|
661
|
+
cleanup();
|
|
662
|
+
const ev = closeEvent(event);
|
|
663
|
+
reject(new Error(`PTY WebSocket closed before opening${ev.code ? ` (${ev.code})` : ""}`));
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
function addSocketListener(socket, type, listener) {
|
|
668
|
+
if (socket.addEventListener) {
|
|
669
|
+
socket.addEventListener(type, listener);
|
|
670
|
+
return () => socket.removeEventListener?.(type, listener);
|
|
671
|
+
}
|
|
672
|
+
if (socket.on) {
|
|
673
|
+
const nodeListener = (...args) => {
|
|
674
|
+
if (type === "message") listener({ data: args[0] });
|
|
675
|
+
else if (type === "close") listener({ code: args[0], reason: args[1] });
|
|
676
|
+
else listener(args[0]);
|
|
677
|
+
};
|
|
678
|
+
socket.on(type, nodeListener);
|
|
679
|
+
return () => socket.off?.(type, nodeListener);
|
|
680
|
+
}
|
|
681
|
+
return () => {
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
function messageData(event) {
|
|
685
|
+
if (event && typeof event === "object" && "data" in event) {
|
|
686
|
+
return event.data;
|
|
687
|
+
}
|
|
688
|
+
return void 0;
|
|
689
|
+
}
|
|
690
|
+
function closeEvent(event) {
|
|
691
|
+
if (!event || typeof event !== "object") return {};
|
|
692
|
+
const raw = event;
|
|
693
|
+
return {
|
|
694
|
+
code: typeof raw.code === "number" ? raw.code : void 0,
|
|
695
|
+
reason: typeof raw.reason === "string" ? raw.reason : void 0
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
function bytesFromMessageData(data) {
|
|
699
|
+
if (typeof data === "string") return new TextEncoder().encode(data);
|
|
700
|
+
if (data instanceof Uint8Array) return data;
|
|
701
|
+
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
702
|
+
if (ArrayBuffer.isView(data)) {
|
|
703
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
704
|
+
}
|
|
705
|
+
if (Array.isArray(data)) {
|
|
706
|
+
const chunks = data.map(bytesFromMessageData);
|
|
707
|
+
const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
708
|
+
const out = new Uint8Array(total);
|
|
709
|
+
let offset = 0;
|
|
710
|
+
for (const chunk of chunks) {
|
|
711
|
+
out.set(chunk, offset);
|
|
712
|
+
offset += chunk.length;
|
|
713
|
+
}
|
|
714
|
+
return out;
|
|
715
|
+
}
|
|
716
|
+
return new Uint8Array();
|
|
717
|
+
}
|
|
718
|
+
function ptyInputBytes(data) {
|
|
719
|
+
if (typeof data === "string") return new TextEncoder().encode(data);
|
|
720
|
+
return data;
|
|
721
|
+
}
|
|
722
|
+
function clampPtyDimension(value) {
|
|
723
|
+
if (!Number.isFinite(value)) return 1;
|
|
724
|
+
return Math.max(1, Math.min(1e3, Math.trunc(value)));
|
|
725
|
+
}
|
|
525
726
|
function normalizeBaseUrl(baseUrl) {
|
|
526
727
|
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
527
728
|
if (!trimmed) throw new Error("baseUrl must not be empty");
|
|
@@ -604,7 +805,10 @@ function parseRunResponse(payload) {
|
|
|
604
805
|
stderr: decodeBytes(stderr, stderrEncoding),
|
|
605
806
|
stderrEncoding,
|
|
606
807
|
exitCode: numberField(body.exit_code, "run response.exit_code"),
|
|
607
|
-
failReason: typeof body.fail_reason === "string" ? body.fail_reason : null
|
|
808
|
+
failReason: typeof body.fail_reason === "string" ? body.fail_reason : null,
|
|
809
|
+
memoryRequestedMib: optionalNumberOrNull(body.memory_requested_mib),
|
|
810
|
+
memoryAchievedMib: optionalNumberOrNull(body.memory_achieved_mib),
|
|
811
|
+
memoryPartial: typeof body.memory_partial === "boolean" ? body.memory_partial : void 0
|
|
608
812
|
};
|
|
609
813
|
}
|
|
610
814
|
if (typeof body.run_id === "string") {
|
|
@@ -675,6 +879,10 @@ function numberField(value, context) {
|
|
|
675
879
|
if (typeof value !== "number") throw new ArkerError("internal", `${context} must be a number`, 200);
|
|
676
880
|
return value;
|
|
677
881
|
}
|
|
882
|
+
function optionalNumberOrNull(value) {
|
|
883
|
+
if (value === null || typeof value === "number") return value;
|
|
884
|
+
return void 0;
|
|
885
|
+
}
|
|
678
886
|
function assertWriteComplete(result, context) {
|
|
679
887
|
if (result.complete && result.written) return;
|
|
680
888
|
throw new ArkerError("internal", `${context} did not complete`, 200);
|