Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/dirty-cows-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@vercel/sandbox": minor
"sandbox": minor
---

Rename sandbox to session, namedSandbox to sandbox
1 change: 1 addition & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"changesets": [
"common-corners-leave",
"dirty-cows-talk",
"fair-pears-dream",
"fresh-rings-rescue",
"legal-rings-work",
Expand Down
8 changes: 4 additions & 4 deletions examples/ai-example/app/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ export async function createSandbox() {
}

export async function uploadFiles(params: {
sandboxId: string;
sandboxName: string;
files: { path: string; content: string }[];
}) {
const sandbox = await Sandbox.get({
name: params.sandboxId,
name: params.sandboxName,
});

const files = params.files.map((file) => ({
Expand Down Expand Up @@ -56,11 +56,11 @@ export async function uploadFiles(params: {
export async function runCommand(params: {
args: string[];
cmd: string;
sandboxId: string;
sandboxName: string;
detached?: boolean;
}) {
const sandbox = await Sandbox.get({
name: params.sandboxId,
name: params.sandboxName,
});

const cmd = await sandbox.runCommand({
Expand Down
6 changes: 3 additions & 3 deletions examples/ai-example/app/api/logs/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ export const maxDuration = 120;
export async function POST(request: Request) {
const body = await request.json();
const cmdId = body.cmdId;
const sandboxId = body.sandboxId;
const sandboxName = body.sandboxName;

if (!cmdId || !sandboxId) {
if (!cmdId || !sandboxName) {
return new Response("Missing required parameters", { status: 400 });
}

const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
const sandbox = await Sandbox.get({ name: sandboxId });
const sandbox = await Sandbox.get({ name: sandboxName });
const command = await sandbox.getCommand(cmdId);

for await (const log of command.logs()) {
Expand Down
28 changes: 14 additions & 14 deletions examples/ai-example/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ export default function SplitScreenChatOptimized() {
const [input, setInput] = useState("");
const [pending, startTransition] = useTransition();
const [logs, setLogs] = useState<string[]>([]);
const [sandboxId, setSandboxId] = useState<string | null>(null);
const [sandboxName, setSandboxName] = useState<string | null>(null);
const [renderPreview, setRenderPreview] = useState(false);
const isReadyRef = useRef(false);

const sandboxIdRef = useRef<string | null>(null);
const sandboxNameRef = useRef<string | null>(null);
const sandboxRoutesRef = useRef<{ subdomain: string; port: number }[] | null>(
null,
);
Expand All @@ -45,41 +45,41 @@ export default function SplitScreenChatOptimized() {
onFinish(message) {
const msg = message.message.parts.find((part) => part.type === "text");
startTransition(async () => {
if (sandboxIdRef.current && sandboxRoutesRef.current && msg) {
if (sandboxNameRef.current && sandboxRoutesRef.current && msg) {
await uploadFiles({
files: extractCodeBlocks(msg!.text),
sandboxId: sandboxIdRef.current,
sandboxName: sandboxNameRef.current,
});

if (!isReadyRef.current) {
isReadyRef.current = true;
const install = await runCommand({
sandboxId: sandboxIdRef.current,
sandboxName: sandboxNameRef.current,
cmd: "npm",
args: ["install", "--loglevel", "info"],
detached: true,
});

for await (const log of getLogs({
sandboxId: sandboxIdRef.current,
sandboxName: sandboxNameRef.current,
cmdId: install.cmdId,
})) {
setLogs((prevLogs) => [...prevLogs, log]);
}

const next = await runCommand({
sandboxId: sandboxIdRef.current,
sandboxName: sandboxNameRef.current,
cmd: "npm",
args: ["run", "dev"],
detached: true,
});
(async () => {
if (!sandboxRoutesRef.current || !sandboxIdRef.current) {
if (!sandboxRoutesRef.current || !sandboxNameRef.current) {
console.error("Sandbox routes or ID is missing");
return;
}
for await (const log of getLogs({
sandboxId: sandboxIdRef.current,
sandboxName: sandboxNameRef.current,
cmdId: next.cmdId,
})) {
setLogs((prevLogs) => [...prevLogs, log]);
Expand Down Expand Up @@ -107,19 +107,19 @@ export default function SplitScreenChatOptimized() {

const handleFormSubmit = useCallback(
(event: React.FormEvent) => {
if (!sandboxId || !url || !routes) {
if (!sandboxName || !url || !routes) {
startTransition(async () => {
const { id, url, routes } = await createSandbox();
setSandboxUrl(url);
setRoutes(routes);
setSandboxId(id);
sandboxIdRef.current = id;
setSandboxName(id);
sandboxNameRef.current = id;
sandboxRoutesRef.current = routes;
});
}
return handleSubmit(event);
},
[sandboxId, url, routes, handleSubmit],
[sandboxName, url, routes, handleSubmit],
);

const handleReload = useCallback(() => {
Expand Down Expand Up @@ -225,7 +225,7 @@ export default function SplitScreenChatOptimized() {
);
}

async function* getLogs(params: { cmdId: string; sandboxId: string }) {
async function* getLogs(params: { cmdId: string; sandboxName: string }) {
const response = await fetch("/api/logs", {
method: "POST",
headers: { "Content-Type": "application/json" },
Expand Down
11 changes: 11 additions & 0 deletions packages/sandbox/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# sandbox

## 3.0.0-beta.6

### Minor Changes

- Rename sandbox to session, namedSandbox to sandbox

### Patch Changes

- Updated dependencies []:
- @vercel/sandbox@2.0.0-beta.5

## 3.0.0-beta.5

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/sandbox/docs/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## `sandbox --help`

```
sandbox 3.0.0-beta.5
sandbox 3.0.0-beta.6

▲ sandbox [options] <command>

Expand Down
2 changes: 1 addition & 1 deletion packages/sandbox/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "sandbox",
"description": "Command line interface for Vercel Sandbox",
"version": "3.0.0-beta.5",
"version": "3.0.0-beta.6",
"scripts": {
"clean": "rm -rf node_modules dist",
"sandbox": "ts-node ./src/sandbox.ts",
Expand Down
4 changes: 2 additions & 2 deletions packages/sandbox/src/commands/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ const listCommand = cmd.command({

const networkPolicy = typeof sandbox.networkPolicy === "string" ? sandbox.networkPolicy : "restricted";
const rows = [
{ field: "vCPUs", value: String(sandbox.vcpus) },
{ field: "Timeout", value: ms(sandbox.timeout, { long: true }) },
{ field: "vCPUs", value: String(sandbox.vcpus ?? "-") },
{ field: "Timeout", value: sandbox.timeout != null ? ms(sandbox.timeout, { long: true }) : "-" },
{ field: "Persistent", value: String(sandbox.persistent) },
{ field: "Network policy", value: String(networkPolicy) },
];
Expand Down
8 changes: 4 additions & 4 deletions packages/sandbox/src/commands/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ export const list = cmd.command({
CREATED: {
value: (s) => timeAgo(s.createdAt),
},
MEMORY: { value: (s) => memoryFormatter.format(s.memory) },
VCPUS: { value: (s) => s.vcpus },
RUNTIME: { value: (s) => s.runtime },
MEMORY: { value: (s) => s.memory != null ? memoryFormatter.format(s.memory) : "-" },
VCPUS: { value: (s) => s.vcpus ?? "-" },
RUNTIME: { value: (s) => s.runtime ?? "-" },
TIMEOUT: {
value: (s) => timeAgo(s.createdAt + s.timeout),
value: (s) => s.timeout != null ? timeAgo(s.createdAt + s.timeout) : "-",
},
SNAPSHOT: { value: (s) => s.currentSnapshotId ?? "-" }
};
Expand Down
7 changes: 1 addition & 6 deletions packages/sandbox/src/commands/remove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@ export const remove = cmd.command({
type: sandboxName,
description: "more sandboxes to remove",
}),
preserveSnapshots: cmd.flag({
long: "preserve-snapshots",
description: "Keep snapshots when removing the sandbox",
}),
scope,
},
async handler({
scope: { token, team, project },
sandboxName,
sandboxNames,
preserveSnapshots,
}) {
const tasks = Array.from(
new Set([sandboxName, ...sandboxNames]),
Expand All @@ -40,7 +35,7 @@ export const remove = cmd.command({
projectId: project,
name,
});
await sandbox.delete({ preserveSnapshots });
await sandbox.delete();
},
}),
);
Expand Down
2 changes: 1 addition & 1 deletion packages/sandbox/src/commands/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const list = cmd.command({
return sandbox.listSessions();
})();

const sessions = sessionData.json.sandboxes;
const sessions = sessionData.json.sessions;

console.log(
table({
Expand Down
4 changes: 2 additions & 2 deletions packages/sandbox/src/commands/snapshots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const list = cmd.command({
: timeAgo(s.expiresAt),
},
SIZE: { value: (s) => formatBytes(s.sizeBytes) },
["SOURCE SESSION"]: { value: (s) => s.sourceSandboxId },
["SOURCE SESSION"]: { value: (s) => s.sourceSessionId },
},
}),
);
Expand Down Expand Up @@ -98,7 +98,7 @@ const get = cmd.command({
CREATED: { value: (s) => timeAgo(s.createdAt) },
EXPIRATION: { value: (s) => s.status === 'deleted' ? chalk.gray.dim('deleted') : timeAgo(s.expiresAt) },
SIZE: { value: (s) => formatBytes(s.sizeBytes) },
["SOURCE SESSION"]: { value: (s) => s.sourceSandboxId },
["SOURCE SESSION"]: { value: (s) => s.sourceSessionId },
},
}),
);
Expand Down
23 changes: 16 additions & 7 deletions packages/sandbox/src/interactive-shell/extend-sandbox-timeout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,27 @@ export async function extendSandboxTimeoutPeriodically(
sandbox: Sandbox,
signal: AbortSignal,
) {
const nextTick = sandbox.createdAt.getTime() + sandbox.timeout;
const session = sandbox.currentSession();
const timeout = session.timeout;
if (timeout == null) return;

const nextTick = session.createdAt.getTime() + timeout;
debug(`next tick: ${new Date(nextTick).toISOString()}`);

while (!signal.aborted) {
const timeout =
sandbox.createdAt.getTime() + sandbox.timeout - Date.now() - BUFFER;
if (timeout > 2000) {
debug(`sleeping for ${timeout}ms until next timeout extension`);
await setTimeout(timeout, null, { signal });
const currentTimeout = session.timeout;
if (currentTimeout == null) return;

const sleepMs =
session.createdAt.getTime() + currentTimeout - Date.now() - BUFFER;
if (sleepMs > 2000) {
debug(`sleeping for ${sleepMs}ms until next timeout extension`);
await setTimeout(sleepMs, null, { signal });
}
await sandbox.extendTimeout(ms("5 minutes"));
const nextTick = sandbox.createdAt.getTime() + sandbox.timeout;
const updatedTimeout = session.timeout;
if (updatedTimeout == null) return;
const nextTick = session.createdAt.getTime() + updatedTimeout;
debug(
`extended sandbox timeout by 5 minutes. next tick: ${new Date(nextTick).toISOString()}`,
);
Expand Down
6 changes: 6 additions & 0 deletions packages/vercel-sandbox/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @vercel/sandbox

## 2.0.0-beta.5

### Minor Changes

- Rename sandbox to session, namedSandbox to sandbox

## 2.0.0-beta.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/vercel-sandbox/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vercel/sandbox",
"version": "2.0.0-beta.4",
"version": "2.0.0-beta.5",
"description": "Software Development Kit for Vercel Sandbox",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
Loading
Loading