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
5 changes: 3 additions & 2 deletions docs/guide/sandboxes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { getSandbox } from 'void/sandbox';

export const POST = defineHandler(async (c) => {
const { command } = await c.req.json<{ command: string }>();
const sandbox = getSandbox('default');
const sandbox = await getSandbox('default');
const result = await sandbox.exec(command);

return c.json(result);
Expand Down Expand Up @@ -58,7 +58,8 @@ Available fields:
```ts
import { getSandbox } from 'void/sandbox';

const sandbox = getSandbox(`user-${user.id}`);
// inside an async handler
const sandbox = await getSandbox(`user-${user.id}`);
await sandbox.writeFile('/tmp/input.txt', 'hello');
const result = await sandbox.exec('cat /tmp/input.txt');
```
Expand Down
19 changes: 18 additions & 1 deletion packages/void/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,24 @@ export function voidPlugin(options?: {
'void/queues': 'export const queues = {};',
'void/storage': 'export const storage = {}; export const createStorage = () => ({});',
'void/isr': 'export const revalidate = async () => {};',
'void/sandbox': 'export const sandbox = {}; export const getSandbox = () => ({});',
// Client stub must mirror the real runtime/sandbox.ts surface so any
// client-side `instanceof SandboxLimitError` check doesn't crash with a
// TypeError, and async `await getSandbox(...)` callers don't silently
// mis-handle a sync return. Throwing here makes accidental client imports
// fail loudly rather than returning a misleading bare `{}`.
'void/sandbox': `
export class SandboxLimitError extends Error {
constructor(reason = 'concurrency', message) {
super(message ?? 'Sandbox limit reached: ' + reason);
this.name = 'SandboxLimitError';
this.reason = reason;
}
}
export async function getSandbox() {
throw new Error('void/sandbox is server-only and cannot be imported by browser code.');
}
export const sandbox = { get: getSandbox };
`,
'void/live': '',
};
const STUB_RESOLVE_FILTER = new RegExp(
Expand Down
2 changes: 1 addition & 1 deletion packages/void/src/router/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2299,7 +2299,7 @@ export function compileWorkerEntry(
const sandboxRuntimePath =
typeof sandbox === 'object' ? (sandbox.runtimePath ?? 'void/sandbox') : 'void/sandbox';
const sandboxImport = hasSandbox
? `import { Sandbox as __VoidSandbox } from "@cloudflare/sandbox";\nimport { __setSandboxBindingName } from ${JSON.stringify(sandboxRuntimePath)};\n`
? `import { VoidPlatformSandbox as __VoidSandbox, __setSandboxBindingName } from ${JSON.stringify(sandboxRuntimePath)};\n`
: '';
const sandboxExport = hasSandbox
? sandboxClassName === 'Sandbox'
Expand Down
Loading