@computesdk/cocoonstack 0.0.0-stage → 1.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import http from 'node:http';\nimport http2 from 'node:http2';\nimport https from 'node:https';\nimport { performance } from 'node:perf_hooks';\nimport { StringDecoder } from 'node:string_decoder';\nimport tls from 'node:tls';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport type {\n CommandResult,\n CreateSandboxOptions,\n FileEntry,\n RunCommandOptions,\n SandboxInfo,\n} from '@computesdk/provider';\n\nconst PROVIDER = 'cocoonstack' as const;\nconst DEFAULT_TEMPLATE = 'node-rt:24.04';\nconst DEFAULT_TTL_SECONDS = 300;\nconst MAX_TTL_SECONDS = 86_400;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 120_000;\nconst COMMAND_HTTP_TIMEOUT_BUFFER_MS = 5_000;\nconst MAX_RESPONSE_BYTES = 16 << 20;\nconst SIZES = [\n { size: 'small', cpu: 1, memoryMb: 512 },\n { size: 'medium', cpu: 2, memoryMb: 1024 },\n { size: 'large', cpu: 4, memoryMb: 4096 },\n { size: 'xlarge', cpu: 4, memoryMb: 8192 },\n { size: '2xlarge', cpu: 8, memoryMb: 16384 },\n] as const;\n\nexport type CocoonstackSize = (typeof SIZES)[number]['size'];\nexport type CocoonstackNet = 'none' | 'egress';\n\nexport interface CocoonstackConfig {\n /** sandboxd endpoint, e.g. https://sandbox.example.com. Falls back to COCOONSTACK_API_URL. */\n baseUrl?: string;\n /** Node or tenant API token. Falls back to COCOONSTACK_API_KEY. */\n apiKey?: string;\n /** Default template, a pool key such as node-rt:24.04. */\n template?: string;\n /** Default network lane. */\n net?: CocoonstackNet;\n /** Default size tier. */\n size?: CocoonstackSize;\n /** Default claim lease in seconds; the node reaps the sandbox after it. */\n ttlSeconds?: number;\n /** HTTP request timeout. */\n requestTimeoutMs?: number;\n /** Open the HTTP/2 session at construction so the first call skips DNS and the TLS handshake; TLS endpoints only. */\n preconnect?: boolean;\n}\n\nexport interface CocoonstackSandbox {\n id: string;\n /** The claim token; every call on the sandbox authenticates with it. */\n token: string;\n template: string;\n net: CocoonstackNet;\n size: CocoonstackSize;\n createdAt: Date;\n deadline: Date;\n config: CocoonstackConfig;\n}\n\nexport class CocoonstackApiError extends Error {\n constructor(\n readonly status: number,\n message: string,\n ) {\n super(message);\n this.name = 'CocoonstackApiError';\n }\n}\n\ninterface Resolved {\n baseUrl: string;\n apiKey: string;\n template: string;\n net: CocoonstackNet;\n size: CocoonstackSize;\n ttlSeconds: number;\n requestTimeoutMs: number;\n}\n\ninterface ClaimResponse {\n id: string;\n token: string;\n deadline: string;\n redirect?: string[];\n}\n\ninterface ExecResponse {\n exit_code: number;\n stdout: string;\n stderr: string;\n}\n\ninterface SandboxRow {\n id: string;\n key: { template: string; net: CocoonstackNet; size: CocoonstackSize };\n deadline: string;\n}\n\ninterface Frame {\n type: string;\n data?: string;\n code?: number;\n pid?: number;\n kind?: string;\n message?: string;\n}\n\ninterface Claim {\n token: string;\n deadline: number;\n}\n\ninterface RelayOptions {\n timeoutMs?: number;\n detach?: boolean;\n onStdout?: (data: string) => void;\n onStderr?: (data: string) => void;\n}\n\ntype Exec = (sandbox: CocoonstackSandbox, command: string, options?: RunCommandOptions) => Promise<CommandResult>;\n\ntype Lane = 'main' | 'release';\n\n// sandboxd scopes a sandbox to its claim token; by-id calls look it up here, keyed per endpoint\nconst claimTokens = new Map<string, Claim>();\n// one HTTP/2 session per origin and lane: a burst multiplexes over one TLS connection,\n// and releases ride their own session so a slow teardown never queues a claim or exec\nconst sessions = new Map<string, http2.ClientHttp2Session>();\nconst sessionStreams = new WeakMap<http2.ClientHttp2Session, number>();\n// building a TLS context parses the CA store; one per process, not one per session\nconst secureContext = tls.createSecureContext();\nconst httpAgent = new http.Agent({ keepAlive: true });\nconst httpsAgent = new https.Agent({ keepAlive: true });\n\nfunction env(name: string): string | undefined {\n return typeof process === 'undefined' ? undefined : process.env[name];\n}\n\nfunction resolve(config: CocoonstackConfig): Resolved {\n const baseUrl = config.baseUrl || env('COCOONSTACK_API_URL') || '';\n if (!baseUrl) {\n throw new Error(\n 'Missing Cocoon Stack endpoint. Pass baseUrl or set COCOONSTACK_API_URL to your sandboxd address.',\n );\n }\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''),\n apiKey: config.apiKey || env('COCOONSTACK_API_KEY') || '',\n template: config.template ?? DEFAULT_TEMPLATE,\n net: config.net ?? 'none',\n size: config.size ?? 'small',\n ttlSeconds: config.ttlSeconds ?? DEFAULT_TTL_SECONDS,\n requestTimeoutMs: config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,\n };\n}\n\nfunction claimKey(resolved: Resolved, id: string): string {\n return `${resolved.baseUrl} ${id}`;\n}\n\nfunction rememberClaim(resolved: Resolved, id: string, token: string, deadline: Date): void {\n const now = Date.now();\n for (const [key, claim] of claimTokens) {\n if (claim.deadline < now) claimTokens.delete(key);\n }\n claimTokens.set(claimKey(resolved, id), { token, deadline: deadline.getTime() });\n}\n\nfunction retainedToken(resolved: Resolved, id: string): string | undefined {\n const key = claimKey(resolved, id);\n const claim = claimTokens.get(key);\n if (!claim) return undefined;\n if (claim.deadline < Date.now()) {\n claimTokens.delete(key);\n return undefined;\n }\n return claim.token;\n}\n\nfunction detail(body: string): string {\n const match = /\"error\"\\s*:\\s*\"([^\"]*)\"/.exec(body);\n return match?.[1] ?? body;\n}\n\nfunction session(origin: string, lane: Lane): http2.ClientHttp2Session {\n const key = `${lane} ${origin}`;\n const live = sessions.get(key);\n if (live && !live.closed && !live.destroyed) return live;\n const created = http2.connect(origin, { secureContext });\n applyHold(created);\n const drop = () => {\n if (sessions.get(key) === created) sessions.delete(key);\n };\n created.on('connect', () => applyHold(created));\n created.on('close', drop);\n created.on('goaway', drop);\n created.on('error', drop);\n sessions.set(key, created);\n return created;\n}\n\n// an idle session must not keep the process alive; a session with streams in flight must\nfunction holdSession(live: http2.ClientHttp2Session): () => void {\n sessionStreams.set(live, (sessionStreams.get(live) ?? 0) + 1);\n applyHold(live);\n return () => {\n sessionStreams.set(live, Math.max(0, (sessionStreams.get(live) ?? 1) - 1));\n applyHold(live);\n };\n}\n\nfunction applyHold(live: http2.ClientHttp2Session): void {\n const socket = live.socket as { ref?: () => void; unref?: () => void } | undefined;\n if (!socket) return;\n if ((sessionStreams.get(live) ?? 0) > 0) socket.ref?.();\n else socket.unref?.();\n}\n\nfunction h2Request(\n origin: string,\n lane: Lane,\n method: string,\n path: string,\n headers: Record<string, string>,\n payload: string | undefined,\n timeoutMs: number,\n signal?: AbortSignal,\n): Promise<{ status: number; text: string }> {\n return new Promise((fulfill, reject) => {\n const live = session(origin, lane);\n const release = holdSession(live);\n const stream = live.request({ ':method': method, ':path': path, ...headers });\n let status = 0;\n let bytes = 0;\n const chunks: Buffer[] = [];\n const abort = () => stream.close(http2.constants.NGHTTP2_CANCEL);\n signal?.addEventListener('abort', abort, { once: true });\n let released = false;\n const done = () => {\n if (released) return;\n released = true;\n signal?.removeEventListener('abort', abort);\n release();\n };\n stream.setTimeout(timeoutMs, () => {\n stream.close(http2.constants.NGHTTP2_CANCEL);\n reject(new Error('sandboxd request timed out'));\n });\n stream.on('response', (responseHeaders) => {\n status = Number(responseHeaders[':status'] ?? 0);\n });\n stream.on('data', (chunk: Buffer) => {\n bytes += chunk.length;\n if (bytes > MAX_RESPONSE_BYTES) {\n stream.close(http2.constants.NGHTTP2_CANCEL);\n reject(new Error(`sandboxd response exceeds ${MAX_RESPONSE_BYTES >> 20} MiB`));\n return;\n }\n chunks.push(chunk);\n });\n stream.on('end', () => {\n done();\n fulfill({ status, text: Buffer.concat(chunks).toString('utf8') });\n });\n stream.on('error', (error: Error) => {\n done();\n reject(signal?.aborted ? (signal.reason instanceof Error ? signal.reason : new Error('aborted')) : error);\n });\n stream.on('close', done);\n stream.end(payload);\n });\n}\n\nfunction h1Request(\n url: URL,\n method: string,\n headers: Record<string, string>,\n payload: string | undefined,\n timeoutMs: number,\n signal?: AbortSignal,\n): Promise<{ status: number; text: string }> {\n return new Promise((fulfill, reject) => {\n const secure = url.protocol === 'https:';\n const client = (secure ? https : http).request(\n url,\n {\n method,\n agent: secure ? httpsAgent : httpAgent,\n timeout: timeoutMs,\n signal,\n headers: {\n ...headers,\n ...(payload === undefined ? {} : { 'content-length': Buffer.byteLength(payload) }),\n },\n },\n (response) => {\n let bytes = 0;\n const chunks: Buffer[] = [];\n response.on('data', (chunk: Buffer) => {\n bytes += chunk.length;\n if (bytes > MAX_RESPONSE_BYTES) {\n client.destroy(new Error(`sandboxd response exceeds ${MAX_RESPONSE_BYTES >> 20} MiB`));\n return;\n }\n chunks.push(chunk);\n });\n response.on('error', reject);\n response.on('end', () => fulfill({ status: response.statusCode ?? 0, text: Buffer.concat(chunks).toString('utf8') }));\n },\n );\n client.on('timeout', () => client.destroy(new Error('sandboxd request timed out')));\n client.on('error', reject);\n client.end(payload);\n });\n}\n\n/** JSON call to sandboxd: HTTP/2 on TLS origins, HTTP/1.1 keep-alive otherwise. */\nasync function request<T>(\n resolved: Resolved,\n token: string,\n method: string,\n path: string,\n body?: unknown,\n signal?: AbortSignal,\n timeoutMs = resolved.requestTimeoutMs,\n lane: Lane = 'main',\n): Promise<T> {\n const url = new URL(`${resolved.baseUrl}${path}`);\n const payload = body === undefined ? undefined : JSON.stringify(body);\n const headers = {\n 'content-type': 'application/json',\n ...(token ? { authorization: `Bearer ${token}` } : {}),\n };\n const { status, text } =\n url.protocol === 'https:'\n ? await h2Request(url.origin, lane, method, `${url.pathname}${url.search}`, headers, payload, timeoutMs, signal)\n : await h1Request(url, method, headers, payload, timeoutMs, signal);\n if (status < 200 || status >= 300) {\n throw new CocoonstackApiError(status, `sandboxd ${method} ${path} failed (${status}): ${detail(text)}`);\n }\n return (text ? JSON.parse(text) : undefined) as T;\n}\n\nfunction isSize(value: string): value is CocoonstackSize {\n return SIZES.some((tier) => tier.size === value);\n}\n\nfunction sizeFor(resolved: Resolved, options?: CreateSandboxOptions): CocoonstackSize {\n if (options?.size !== undefined) {\n if (!isSize(options.size)) {\n throw new Error(\n `Unknown Cocoon Stack size ${JSON.stringify(options.size)}; one of ${SIZES.map((tier) => tier.size).join(', ')}.`,\n );\n }\n return options.size;\n }\n const cpu = options?.vcpus ?? options?.cpus ?? options?.cpu;\n const memoryMb = options?.memoryMb ?? options?.memoryMiB ?? options?.memMiB ?? options?.memory;\n if (cpu === undefined && memoryMb === undefined) return resolved.size;\n const tier = SIZES.find((candidate) => candidate.cpu >= (cpu ?? 0) && candidate.memoryMb >= (memoryMb ?? 0));\n if (!tier) {\n throw new Error(\n `No Cocoon Stack size tier offers ${cpu ?? '-'} CPU / ${memoryMb ?? '-'} MB; the largest is 2xlarge (8 CPU / 16384 MB).`,\n );\n }\n return tier.size;\n}\n\nfunction ttlFor(resolved: Resolved, options?: CreateSandboxOptions): number {\n if (!options?.timeout) return resolved.ttlSeconds;\n return Math.min(MAX_TTL_SECONDS, Math.ceil(options.timeout / 1000));\n}\n\nfunction fromRow(config: CocoonstackConfig, row: SandboxRow, token: string): CocoonstackSandbox {\n return {\n id: row.id,\n token,\n template: row.key.template,\n net: row.key.net,\n size: row.key.size,\n createdAt: new Date(),\n deadline: new Date(row.deadline),\n config,\n };\n}\n\nasync function index(resolved: Resolved): Promise<SandboxRow[]> {\n const listing = await request<{ sandboxes: SandboxRow[] }>(resolved, resolved.apiKey, 'GET', '/v1/sandboxes');\n return listing.sandboxes;\n}\n\n/** One silkd RPC per connection: HTTP Upgrade, one JSON request line, newline-delimited frames back. */\nfunction relay(\n sandbox: CocoonstackSandbox,\n resolved: Resolved,\n rpc: Record<string, unknown>,\n options: RelayOptions,\n): Promise<Omit<CommandResult, 'durationMs'>> {\n return new Promise((fulfill, reject) => {\n const url = new URL(`${resolved.baseUrl}/v1/sandboxes/${encodeURIComponent(sandbox.id)}/agent`);\n const secure = url.protocol === 'https:';\n const client = (secure ? https : http).request(url, {\n method: 'GET',\n agent: secure ? httpsAgent : httpAgent,\n headers: { upgrade: 'silkd', connection: 'Upgrade', authorization: `Bearer ${sandbox.token}` },\n });\n let settled = false;\n let timer: NodeJS.Timeout | undefined;\n const finish = (outcome: () => void) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n outcome();\n };\n if (options.timeoutMs) {\n timer = setTimeout(() => {\n finish(() => reject(new Error(`Command timed out after ${options.timeoutMs} ms`)));\n client.destroy();\n }, options.timeoutMs);\n }\n client.on('response', (response) => {\n let body = '';\n response.setEncoding('utf8');\n response.on('data', (chunk: string) => {\n body += chunk;\n });\n response.on('end', () =>\n finish(() =>\n reject(\n new CocoonstackApiError(\n response.statusCode ?? 0,\n `sandboxd agent relay refused (${response.statusCode}): ${detail(body)}`,\n ),\n ),\n ),\n );\n });\n client.on('upgrade', (_response, socket, head) => {\n const out = new StringDecoder('utf8');\n const err = new StringDecoder('utf8');\n let stdout = '';\n let stderr = '';\n let frames = 0;\n let lastOut = 0;\n let lastErr = 0;\n let pending = head.toString('utf8');\n const handle = (frame: Frame) => {\n switch (frame.type) {\n case 'started':\n if (options.detach) {\n finish(() => fulfill({ exitCode: 0, stdout: String(frame.pid ?? ''), stderr: '' }));\n socket.destroy();\n }\n break;\n case 'stdout': {\n lastOut = ++frames;\n const text = out.write(Buffer.from(frame.data ?? '', 'base64'));\n stdout += text;\n if (text) options.onStdout?.(text);\n break;\n }\n case 'stderr': {\n lastErr = ++frames;\n const text = err.write(Buffer.from(frame.data ?? '', 'base64'));\n stderr += text;\n if (text) options.onStderr?.(text);\n break;\n }\n case 'exit': {\n const tailOut = out.end();\n const tailErr = err.end();\n stdout += tailOut;\n stderr += tailErr;\n // each tail came from its stream's last frame, so replay them in that order\n const tails: [number, string, ((text: string) => void) | undefined][] = [\n [lastOut, tailOut, options.onStdout],\n [lastErr, tailErr, options.onStderr],\n ];\n for (const [, text, notify] of tails.sort((a, b) => a[0] - b[0])) {\n if (text) notify?.(text);\n }\n finish(() => fulfill({ exitCode: frame.code ?? 0, stdout, stderr }));\n socket.destroy();\n break;\n }\n case 'error':\n finish(() => reject(new Error(`silkd ${frame.kind ?? 'error'}: ${frame.message ?? ''}`)));\n socket.destroy();\n break;\n default:\n break;\n }\n };\n socket.setEncoding('utf8');\n socket.on('data', (chunk: string) => {\n pending += chunk;\n let newline = pending.indexOf('\\n');\n while (newline >= 0) {\n const line = pending.slice(0, newline);\n pending = pending.slice(newline + 1);\n if (line.trim()) {\n try {\n handle(JSON.parse(line) as Frame);\n } catch (error: unknown) {\n finish(() => reject(error instanceof Error ? error : new Error(String(error))));\n socket.destroy();\n return;\n }\n }\n newline = pending.indexOf('\\n');\n }\n });\n socket.on('error', (error: Error) => finish(() => reject(error)));\n socket.on('close', () => finish(() => reject(new Error('Agent relay closed before the command exited'))));\n socket.write(`${JSON.stringify({ v: 1, ...rpc })}\\n`);\n });\n client.on('error', (error: Error) => finish(() => reject(error)));\n client.end();\n });\n}\n\n/** Streaming and detached commands ride the relay; everything else is one buffered exec request. */\nasync function exec(sandbox: CocoonstackSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> {\n const started = performance.now();\n const resolved = resolve(sandbox.config);\n const argv = ['bash', '-c', command];\n if (options?.background || options?.onStdout || options?.onStderr) {\n const result = await relay(\n sandbox,\n resolved,\n {\n op: 'exec',\n argv,\n ...(options.cwd ? { cwd: options.cwd } : {}),\n ...(options.env ? { env: options.env } : {}),\n ...(options.background ? { detach: true } : {}),\n },\n {\n timeoutMs: options.timeout ?? resolved.requestTimeoutMs,\n detach: options.background,\n onStdout: options.onStdout,\n onStderr: options.onStderr,\n },\n );\n return { ...result, durationMs: performance.now() - started };\n }\n try {\n const result = await request<ExecResponse>(\n resolved,\n sandbox.token,\n 'POST',\n `/v1/sandboxes/${encodeURIComponent(sandbox.id)}/exec`,\n {\n argv,\n ...(options?.cwd ? { cwd: options.cwd } : {}),\n ...(options?.env ? { env: options.env } : {}),\n ...(options?.timeout ? { timeout_seconds: Math.ceil(options.timeout / 1000) } : {}),\n },\n undefined,\n options?.timeout ? options.timeout + COMMAND_HTTP_TIMEOUT_BUFFER_MS : resolved.requestTimeoutMs,\n );\n return {\n exitCode: result.exit_code,\n stdout: result.stdout,\n stderr: result.stderr,\n durationMs: performance.now() - started,\n };\n } catch (error: unknown) {\n if (error instanceof CocoonstackApiError && error.status === 504) {\n throw new Error(`Command timed out after ${options?.timeout} ms`);\n }\n throw error;\n }\n}\n\nasync function shell(runCommand: Exec, sandbox: CocoonstackSandbox, command: string, failure: string): Promise<string> {\n const result = await runCommand(sandbox, command);\n if (result.exitCode !== 0) {\n throw new Error(`${failure}: ${result.stderr.trim() || `exit ${result.exitCode}`}`);\n }\n return result.stdout;\n}\n\nconst provider = defineProvider<CocoonstackSandbox, CocoonstackConfig>({\n name: PROVIDER,\n methods: {\n sandbox: {\n create: async (config, options) => {\n const resolved = resolve(config);\n const template = options?.templateId ?? options?.image ?? resolved.template;\n const size = sizeFor(resolved, options);\n const claimed = await request<ClaimResponse>(\n resolved,\n resolved.apiKey,\n 'POST',\n '/v1/claim',\n { template, net: resolved.net, size, ttl_seconds: ttlFor(resolved, options) },\n options?.signal,\n );\n if (claimed.redirect) {\n throw new Error(\n `sandboxd redirected the claim to ${claimed.redirect.join(', ')}; point baseUrl at a node that serves the pool.`,\n );\n }\n const deadline = new Date(claimed.deadline);\n rememberClaim(resolved, claimed.id, claimed.token, deadline);\n const sandbox: CocoonstackSandbox = {\n id: claimed.id,\n token: claimed.token,\n template,\n net: resolved.net,\n size,\n createdAt: new Date(),\n deadline,\n config,\n };\n return { sandbox, sandboxId: sandbox.id };\n },\n\n getById: async (config, sandboxId) => {\n const resolved = resolve(config);\n const token = retainedToken(resolved, sandboxId);\n if (token === undefined) return null;\n const row = (await index(resolved)).find((candidate) => candidate.id === sandboxId);\n return row ? { sandbox: fromRow(config, row, token), sandboxId } : null;\n },\n\n list: async (config) => {\n const resolved = resolve(config);\n return (await index(resolved)).flatMap((row) => {\n const token = retainedToken(resolved, row.id);\n return token === undefined ? [] : [{ sandbox: fromRow(config, row, token), sandboxId: row.id }];\n });\n },\n\n destroy: async (config, sandboxId) => {\n const resolved = resolve(config);\n try {\n await request<void>(\n resolved,\n retainedToken(resolved, sandboxId) ?? resolved.apiKey,\n 'POST',\n `/v1/sandboxes/${encodeURIComponent(sandboxId)}/release`,\n undefined,\n undefined,\n resolved.requestTimeoutMs,\n 'release',\n );\n } catch (error: unknown) {\n if (!(error instanceof CocoonstackApiError && error.status === 404)) throw error;\n }\n claimTokens.delete(claimKey(resolved, sandboxId));\n },\n\n runCommand: exec,\n\n streamCommand: exec,\n\n getInfo: async (sandbox): Promise<SandboxInfo> => ({\n id: sandbox.id,\n provider: PROVIDER,\n status: 'running',\n createdAt: sandbox.createdAt,\n timeout: Math.max(0, sandbox.deadline.getTime() - Date.now()),\n metadata: {\n template: sandbox.template,\n net: sandbox.net,\n size: sandbox.size,\n deadline: sandbox.deadline.toISOString(),\n },\n }),\n\n getUrl: async (sandbox, options): Promise<string> => {\n const resolved = resolve(sandbox.config);\n const preview = await request<{ url: string }>(\n resolved,\n resolved.apiKey,\n 'POST',\n `/v1/sandboxes/${encodeURIComponent(sandbox.id)}/preview`,\n { token: sandbox.token, port: options.port, ttl_seconds: 0 },\n );\n return preview.url;\n },\n\n filesystem: {\n readFile: async (sandbox, path, runCommand): Promise<string> =>\n shell(runCommand, sandbox, `cat \"${shellPath(path)}\"`, `Failed to read ${path}`),\n\n writeFile: async (sandbox, path, content, runCommand): Promise<void> => {\n const encoded = Buffer.from(content, 'utf8').toString('base64');\n const cut = path.lastIndexOf('/');\n const directory = cut < 0 ? '.' : path.slice(0, cut) || '/';\n await shell(\n runCommand,\n sandbox,\n `mkdir -p \"${shellPath(directory)}\" && printf %s \"${escapeShellArg(encoded)}\" | base64 -d > \"${shellPath(path)}\"`,\n `Failed to write ${path}`,\n );\n },\n\n mkdir: async (sandbox, path, runCommand): Promise<void> => {\n await shell(runCommand, sandbox, `mkdir -p \"${shellPath(path)}\"`, `Failed to create ${path}`);\n },\n\n readdir: async (sandbox, path, runCommand): Promise<FileEntry[]> => {\n // NUL-separated records: a name may hold spaces or newlines, which a line-based listing loses\n const listing = await shell(\n runCommand,\n sandbox,\n `find \"${shellPath(path)}\" -mindepth 1 -maxdepth 1 -printf '%y\\\\t%s\\\\t%T@\\\\t%f\\\\0'`,\n `Failed to list ${path}`,\n );\n return listing.split('\\0').flatMap((record) => {\n if (!record) return [];\n const [kind, size, modified, ...rest] = record.split('\\t');\n const name = rest.join('\\t');\n if (!name) return [];\n return [\n {\n name,\n type: kind === 'd' ? ('directory' as const) : ('file' as const),\n size: Number.parseInt(size, 10) || 0,\n modified: new Date(Number.parseFloat(modified) * 1000),\n },\n ];\n });\n },\n\n exists: async (sandbox, path, runCommand): Promise<boolean> => {\n const result = await runCommand(sandbox, `test -e \"${shellPath(path)}\"`);\n return result.exitCode === 0;\n },\n\n remove: async (sandbox, path, runCommand): Promise<void> => {\n await shell(runCommand, sandbox, `rm -rf \"${shellPath(path)}\"`, `Failed to remove ${path}`);\n },\n },\n\n getInstance: (sandbox) => sandbox,\n },\n },\n});\n\n/** Cocoon Stack provider; `preconnect` opens the HTTP/2 session at construction instead of on the first call. */\nexport const cocoonstack: typeof provider = (config) => {\n if (config.preconnect) preconnect(config.baseUrl || env('COCOONSTACK_API_URL') || '');\n return provider(config);\n};\n\nexport default cocoonstack;\n\n// a relative path starting with - or ( reads as an option or a find expression until it is anchored\nfunction shellPath(path: string): string {\n return escapeShellArg(path.startsWith('/') ? path : `./${path}`);\n}\n\n// a malformed endpoint is reported by the first call, not by the warm-up\nfunction preconnect(baseUrl: string): void {\n let url: URL;\n try {\n url = new URL(baseUrl);\n } catch {\n return;\n }\n if (url.protocol === 'https:') session(url.origin, 'main');\n}\n"],"mappings":"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","names":["tier"]}
package/package.json CHANGED
@@ -1,6 +1,65 @@
1
1
  {
2
2
  "name": "@computesdk/cocoonstack",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.1",
4
+ "description": "Cocoon Stack provider for ComputeSDK - self-hosted microVM sandboxes served from warm pools by sandboxd",
5
+ "author": "CMGS",
6
+ "license": "MIT",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "keywords": [
21
+ "computesdk",
22
+ "cocoonstack",
23
+ "cocoon",
24
+ "sandbox",
25
+ "microvm",
26
+ "cloud-hypervisor",
27
+ "self-hosted",
28
+ "code-execution",
29
+ "compute",
30
+ "provider"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/computesdk/computesdk.git",
35
+ "directory": "packages/cocoonstack"
36
+ },
37
+ "homepage": "https://github.com/cocoonstack/sandbox",
38
+ "bugs": {
39
+ "url": "https://github.com/computesdk/computesdk/issues"
40
+ },
41
+ "dependencies": {
42
+ "@computesdk/provider": "2.1.23",
43
+ "computesdk": "4.1.17"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^20.0.0",
47
+ "@vitest/coverage-v8": "^1.0.0",
48
+ "eslint": "^8.37.0",
49
+ "rimraf": "^5.0.0",
50
+ "tsup": "^8.0.0",
51
+ "typescript": "^5.0.0",
52
+ "vitest": "^1.0.0",
53
+ "@computesdk/test-utils": "2.0.6"
54
+ },
55
+ "scripts": {
56
+ "build": "tsup",
57
+ "clean": "rimraf dist",
58
+ "dev": "tsup --watch",
59
+ "test": "vitest run",
60
+ "test:watch": "vitest watch",
61
+ "test:coverage": "vitest run --coverage",
62
+ "typecheck": "tsc --noEmit",
63
+ "lint": "eslint"
64
+ }
6
65
  }