unfazed 0.0.1 → 0.2.0

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,"file":"unfazed.js","sourceRoot":"","sources":["../src/unfazed.ts"],"names":[],"mappings":"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","sourcesContent":["import { UnfazedClient, type ClientOptions, type RequestOptions } from \"./client.js\";\nimport {\n DEPLOYMENT_NOT_FOUND,\n UnfazedConflictError,\n UnfazedDeployError,\n UnfazedGraphQLError,\n UnfazedNotFoundError,\n WORKSPACE_NOT_FOUND,\n isDuplicateWorkspaceName,\n isNotFoundSentinel as isNotFound,\n looksLikeCASConflict,\n} from \"./errors.js\";\nimport * as ops from \"./operations.js\";\nimport type {\n CreateDeploymentInput,\n DeploymentFieldsFragment,\n ListDeploymentsInput,\n ServiceMode,\n ServiceRuntime,\n SdkCreateWorkspaceMutation,\n} from \"./generated/graphql.js\";\nimport { pollWithBackoff, resolveWaitOptions, type WaitOptions } from \"./wait.js\";\n\n/** A deployment as the workflow layer returns it. */\nexport type Deployment = DeploymentFieldsFragment;\n\n/**\n * A workspace as {@link Unfazed.createWorkspace} and\n * {@link Unfazed.ensureWorkspace} return it.\n *\n * Derived from the generated mutation type rather than hand-written, so the\n * two documents selecting these fields cannot drift apart without a compile\n * error — which is exactly what makes `ensureWorkspace` able to return either\n * a listed or a freshly created workspace under one type.\n */\nexport type Workspace = SdkCreateWorkspaceMutation[\"createWorkspace\"][\"workspace\"];\n\n/** Options for {@link Unfazed.deleteWorkspace}. */\nexport type DeleteWorkspaceOptions = {\n /**\n * Also delete every deployment snapshotted from the workspace, stopping\n * their service VMs. **Defaults to `true`** — see the method docs for why.\n */\n withDeployments?: boolean;\n /** Resolve `false` instead of throwing when the workspace is not visible. */\n ignoreNotFound?: boolean;\n} & RequestOptions;\n\n/** Options for {@link Unfazed.deleteDeployment}. */\nexport type DeleteDeploymentOptions = {\n /** Resolve `false` instead of throwing when the deployment is not visible. */\n ignoreNotFound?: boolean;\n} & RequestOptions;\n\n/** A file record returned by any write/list operation. */\nexport interface WorkspaceFile {\n path: string;\n sizeBytes: number;\n size: string;\n sha256: string;\n updatedAt: string;\n}\n\n/** One env var in a workspace- or app-scoped view. Secret values are never returned. */\nexport interface EnvVar {\n name: string;\n value: string | null;\n secret: boolean;\n alias: string | null;\n inherited: boolean;\n masked: boolean;\n updatedAt: string;\n}\n\n/**\n * A file's contents for {@link Unfazed.writeFiles}.\n *\n * A bare string is text — the overwhelmingly common case, and what makes\n * `{ \"server.ts\": code }` read well. Binary goes through `bytes` or `base64`,\n * which route to `writeWorkspaceBase64File` instead.\n */\nexport type FileContent =\n | string\n | { text: string }\n | { base64: string }\n | { bytes: Uint8Array | ArrayBuffer };\n\n/** Files keyed by workspace-relative path. */\nexport type FilesMap = Record<string, FileContent>;\n\nexport interface WriteFilesOptions {\n /**\n * Max files per GraphQL request. Default 20.\n *\n * The batch is one document with N aliased root fields; too many at once\n * makes a single oversized request whose failure is all-or-nothing to\n * diagnose. Twenty keeps a typical app to one or two round trips.\n */\n batchSize?: number;\n /**\n * Max total payload bytes per request. Default 4 MiB. Whichever limit trips\n * first closes the batch, so one large file cannot blow the request up.\n */\n maxBatchBytes?: number;\n signal?: AbortSignal;\n}\n\n/** Common options for the deploy helpers. */\nexport interface DeployOptions {\n workspaceId: string;\n alias?: string;\n /**\n * Block until the deployment reaches a terminal status.\n *\n * `createDeployment` returns BUILDING immediately; the build, VM boot and\n * health probe run in the background. With `wait: true` the call resolves\n * only on READY and throws {@link UnfazedDeployError} on FAILED — which is\n * what makes a one-script deploy possible.\n */\n wait?: boolean;\n /** Backoff/timeout knobs used when `wait` is true. */\n waitOptions?: WaitOptions;\n signal?: AbortSignal;\n}\n\nexport interface DeployServiceOptions extends DeployOptions {\n /** Omit to auto-detect: a root go.mod+main.go is GO, otherwise BUN. */\n runtime?: ServiceRuntime;\n /** Omit for ON_DEMAND. Only set ALWAYS_ON to keep the VM warm. */\n serviceMode?: ServiceMode;\n healthPath?: string;\n /** Standard 5-field cron spec. Prefer ON_DEMAND + cron over ALWAYS_ON. */\n cronSchedule?: string;\n /** Path the cron tick POSTs to. Defaults to /cron when cronSchedule is set. */\n cronPath?: string;\n}\n\nexport interface DeployStaticOptions extends DeployOptions {\n /** Serve index.html for missing paths (single-page apps). */\n spaMode?: boolean;\n}\n\nexport interface DeployBoxOptions extends DeployOptions {\n /** VM size. Omit for platform defaults (2048 MiB / 2 vCPU / 8 GiB disk). */\n resources?: { memMiB?: number; vcpus?: number; diskGiB?: number };\n}\n\nexport interface RollbackOptions {\n /** The alias to roll back. */\n alias: string;\n /**\n * Release to restore. Omit to pick the most recent READY release that is not\n * the current holder — i.e. \"undo the last deploy\".\n */\n to?: string;\n /**\n * Re-list-and-retry attempts when the compare-and-swap guard is rejected.\n * Default 1. Each retry refreshes the guard from a fresh read; the TARGET\n * release stays pinned, so a retry can never silently roll back to something\n * other than what was chosen.\n *\n * Ignored when {@link expectedCurrentId} is set — see there.\n */\n retries?: number;\n /**\n * The release you believe currently holds the alias. When set, the rollback\n * proceeds only if that is still true.\n *\n * This turns the rollback from \"undo whatever is live now\" into a checked\n * operation: if the live holder is anything else, you get\n * {@link UnfazedConflictError} BEFORE any mutation is sent, so a rollback\n * script can never act on a world that moved since you inspected it.\n *\n * It also disables the CAS retry, necessarily: a rejected guard means the\n * alias moved, and the alias having moved is precisely the precondition you\n * asked to be enforced. Retrying would refresh the guard to the new holder\n * and roll back the very deploy the precondition existed to protect.\n */\n expectedCurrentId?: string;\n signal?: AbortSignal;\n}\n\nexport interface UnfazedOptions extends ClientOptions {\n /** Use an existing core client instead of constructing one. */\n client?: UnfazedClient;\n}\n\n/**\n * Layer 2 — the agent workflow layer.\n *\n * Wraps the chains an agent actually performs (create → write → deploy → wait\n * → read logs → roll back) so a code-mode script does in one call what would\n * otherwise be many round trips through a model's context. Everything here is\n * built on {@link UnfazedClient}, exposed as `.client` for anything not\n * wrapped.\n *\n * ```ts\n * const unfazed = new Unfazed(); // reads UNFZ_API_TOKEN\n * const ws = await unfazed.createWorkspace(\"hello\");\n * await unfazed.writeFiles(ws.id, { \"server.ts\": code });\n * const app = await unfazed.deployService({ workspaceId: ws.id, alias: \"hello\", wait: true });\n * console.log(app.url);\n * ```\n */\nexport class Unfazed {\n /** The underlying typed GraphQL client. Use it for un-wrapped operations. */\n readonly client: UnfazedClient;\n\n constructor(options: UnfazedOptions = {}) {\n const { client, ...clientOptions } = options;\n this.client = client ?? new UnfazedClient(clientOptions);\n }\n\n /* ---------------------------------------------------------------- identity */\n\n /** Who this token authenticates as, plus usage and resource limits. */\n async whoami(options?: RequestOptions) {\n const data = await this.client.query(ops.WhoamiDocument, {}, options);\n return data.whoami;\n }\n\n /* -------------------------------------------------------------- workspaces */\n\n /** Creates a source workspace — the container for files, env and deployments. */\n async createWorkspace(name: string, options?: RequestOptions) {\n const data = await this.client.mutate(ops.CreateWorkspaceDocument, { name }, options);\n return data.createWorkspace.workspace;\n }\n\n /** Workspaces visible to this token. */\n async listWorkspaces(options?: RequestOptions) {\n const data = await this.client.query(ops.ListWorkspacesDocument, {}, options);\n return data.workspaces;\n }\n\n /**\n * Deletes a workspace and everything anchored to it — deployments, env, and\n * a BOX's persistent data disk. Not recoverable.\n *\n * **The cascade is opt-out, not opt-in.** The server refuses to delete a\n * workspace that has ANY deployment history — including FAILED records, and\n * including deployments whose alias was long since taken over by something\n * else — unless the mutation carries `withDeployments`. Since almost every\n * workspace an agent creates gets deployed at least once, defaulting to\n * `false` would make this method fail on nearly every real workspace, so it\n * defaults to **`true`**: the behaviour this docstring has always promised.\n *\n * Pass `withDeployments: false` for the strict variant, which refuses rather\n * than cascading and is the safer choice when you are deleting a workspace\n * you did not create:\n *\n * ```ts\n * await unfazed.deleteWorkspace(ws.id); // cascade\n * await unfazed.deleteWorkspace(ws.id, { withDeployments: false }); // refuse if deployed\n * await unfazed.deleteWorkspace(id, { ignoreNotFound: true }); // false, not a throw\n * ```\n *\n * With `ignoreNotFound` a workspace that is absent (or belongs to someone\n * else — the server returns one indistinguishable sentinel for both, on\n * purpose) resolves to `false` instead of throwing, which makes teardown in\n * a `finally` block idempotent.\n */\n async deleteWorkspace(\n workspaceId: string,\n options: DeleteWorkspaceOptions = {},\n ): Promise<boolean> {\n const withDeployments = options.withDeployments ?? true;\n try {\n const data = await this.client.mutate(\n ops.DeleteWorkspaceDocument,\n { workspaceID: workspaceId, withDeployments },\n options,\n );\n return data.deleteWorkspace.ok;\n } catch (e) {\n if (options.ignoreNotFound && isNotFound(e, WORKSPACE_NOT_FOUND)) return false;\n throw e;\n }\n }\n\n /**\n * Returns the workspace named `name`, creating it only if it does not exist.\n *\n * Workspace names are unique per owner, case-insensitively — a second\n * `createWorkspace(\"Hello\")` after a `createWorkspace(\"hello\")` is an error,\n * not a second workspace. That makes the bare create a poor fit for any\n * script that might run twice; this is the re-runnable form.\n *\n * ```ts\n * const ws = await unfazed.ensureWorkspace(\"greeter\"); // safe to re-run\n * ```\n *\n * Costs one list, plus one create only on a miss. The create is still\n * guarded: if a concurrent caller wins the race, the duplicate-name error is\n * caught and the now-existing workspace is returned instead of thrown.\n */\n async ensureWorkspace(name: string, options?: RequestOptions) {\n const existing = await this.#findWorkspaceByName(name, options);\n if (existing) return existing;\n\n try {\n return await this.createWorkspace(name, options);\n } catch (e) {\n // Lost a create/create race, or the server's case folding is stricter\n // than ours. Either way the workspace exists now — re-read rather than\n // failing a script whose intent was \"make sure this exists\".\n if (!isDuplicateWorkspaceName(e)) throw e;\n const raced = await this.#findWorkspaceByName(name, options);\n if (raced) return raced;\n // The name is taken by something we cannot see. Surface the real error.\n throw e;\n }\n }\n\n /* ------------------------------------------------------------------- files */\n\n /**\n * Writes many files in as few requests as possible.\n *\n * The API is one-file-per-mutation, so writing a 12-file app naively costs 12\n * round trips. This batches them into a single GraphQL document with one\n * ALIASED root field per file (`f0: writeWorkspaceTextFile(...)`,\n * `f1: ...`), which the server resolves in one request.\n *\n * ```ts\n * await unfazed.writeFiles(ws.id, {\n * \"server.ts\": serverCode,\n * \"unfazed.json\": JSON.stringify({ entry: \"server.ts\" }),\n * \"public/logo.png\": { bytes: pngBytes },\n * });\n * ```\n *\n * Batches are NOT atomic: GraphQL resolves each aliased field independently,\n * so a partial failure leaves earlier writes committed. The thrown\n * {@link UnfazedGraphQLError} carries `data` with whichever aliases\n * succeeded, and `error.path` identifies the ones that did not.\n */\n async writeFiles(\n workspaceId: string,\n files: FilesMap,\n options: WriteFilesOptions = {},\n ): Promise<WorkspaceFile[]> {\n const entries = Object.entries(files).map(([path, content]) => normalizeFile(path, content));\n if (entries.length === 0) return [];\n\n const batchSize = options.batchSize ?? 20;\n const maxBatchBytes = options.maxBatchBytes ?? 4 * 1024 * 1024;\n\n const written: WorkspaceFile[] = [];\n for (const batch of chunkFiles(entries, batchSize, maxBatchBytes)) {\n written.push(...(await this.#writeBatch(workspaceId, batch, options.signal)));\n }\n return written;\n }\n\n /** Writes one text file. Prefer {@link writeFiles} for more than one. */\n async writeFile(\n workspaceId: string,\n path: string,\n text: string,\n options?: RequestOptions,\n ): Promise<WorkspaceFile> {\n const data = await this.client.mutate(\n ops.WriteTextFileDocument,\n { workspaceID: workspaceId, path, text },\n options,\n );\n return data.writeWorkspaceTextFile.file;\n }\n\n /** Writes one binary file. Accepts raw bytes or a base64 string. */\n async writeBinaryFile(\n workspaceId: string,\n path: string,\n content: Uint8Array | ArrayBuffer | { base64: string },\n options?: RequestOptions,\n ): Promise<WorkspaceFile> {\n const contentBase64 = \"base64\" in content ? content.base64 : toBase64(content);\n const data = await this.client.mutate(\n ops.WriteBase64FileDocument,\n { workspaceID: workspaceId, path, contentBase64 },\n options,\n );\n return data.writeWorkspaceBase64File.file;\n }\n\n /** Lists workspace files (paginated). */\n async listFiles(\n workspaceId: string,\n input: { limit?: number; offset?: number; order?: string } = {},\n options?: RequestOptions,\n ) {\n const data = await this.client.query(\n ops.ListFilesDocument,\n { input: { workspaceID: workspaceId, ...input } },\n options,\n );\n return data.workspaceFilesPage;\n }\n\n /** Reads a text file, optionally a byte range of it. Null when absent. */\n async readFile(\n workspaceId: string,\n path: string,\n input: { offset?: number; limit?: number } = {},\n options?: RequestOptions,\n ) {\n const data = await this.client.query(\n ops.ReadFileDocument,\n { input: { workspaceID: workspaceId, path, ...input } },\n options,\n );\n return data.readWorkspaceFile;\n }\n\n /**\n * Deletes a workspace file.\n *\n * Returns `false` when there was nothing to delete — an absent path is not\n * an error. See the `ok: false` convention on {@link deleteEnv}.\n */\n async deleteFile(\n workspaceId: string,\n path: string,\n options?: RequestOptions,\n ): Promise<boolean> {\n const data = await this.client.mutate(\n ops.DeleteFileDocument,\n { workspaceID: workspaceId, path },\n options,\n );\n return data.deleteWorkspaceFile.ok;\n }\n\n /* ----------------------------------------------------------------- deploys\n *\n * Every deploy method here MINTS A NEW RELEASE on every call. There is no\n * content dedupe: deploying byte-identical files twice produces two distinct\n * releases with two ids, both real, both counting against retention (which\n * keeps only the most recent few per alias and prunes the rest). Deploying\n * in a retry loop is therefore not free — it churns the release history and\n * can push a release you still wanted to roll back to out of retention.\n * Check {@link getDeployment} or {@link listReleases} before redeploying if\n * you only meant to converge.\n */\n\n /**\n * Deploys the workspace as a SERVICE (an HTTP server).\n *\n * With `wait: true` this resolves only once the build, VM boot and health\n * probe have all passed.\n *\n * Passing the same `alias` again redeploys that alias — a new release that\n * takes over the alias when it goes READY. Omitting `alias` lets the server\n * generate one, which means a different app on every call.\n */\n deployService(options: DeployServiceOptions): Promise<Deployment> {\n const { workspaceId, alias, runtime, serviceMode, healthPath, cronSchedule, cronPath } =\n options;\n return this.#deploy(\n {\n workspaceID: workspaceId,\n kind: \"SERVICE\",\n ...(alias === undefined ? {} : { alias }),\n ...(runtime === undefined ? {} : { runtime }),\n ...(serviceMode === undefined ? {} : { serviceMode }),\n ...(healthPath === undefined ? {} : { healthPath }),\n ...(cronSchedule === undefined ? {} : { cronSchedule }),\n ...(cronPath === undefined ? {} : { cronPath }),\n },\n options,\n );\n }\n\n /** Deploys the workspace as a STATIC site. */\n deployStatic(options: DeployStaticOptions): Promise<Deployment> {\n const { workspaceId, alias, spaMode } = options;\n return this.#deploy(\n {\n workspaceID: workspaceId,\n kind: \"STATIC\",\n ...(alias === undefined ? {} : { alias }),\n ...(spaMode === undefined ? {} : { spaMode }),\n },\n options,\n );\n }\n\n /**\n * Deploys a BOX: a persistent always-on Linux VM with a data disk that\n * survives stops and redeploys. A dev machine, not an HTTP service. The\n * result's `sshCommand` is how you get in.\n *\n * ⚠️ **Omitting `alias` creates a NEW BOX every single call.** There is no\n * \"the workspace's box\" to update: with no alias the server generates a\n * fresh random one, so a script run twice leaves you with two box records,\n * not one redeployed box.\n *\n * The data disk, meanwhile, is keyed by WORKSPACE — one disk, shared by\n * every box in the workspace, and it is the box's real identity. Since only\n * one VM can hold that disk read-write, the second box cannot even start\n * while the first is running (`box data disk for workspace ... is attached\n * to VM ...; stop it first`). The result is a pile of dead box records\n * fighting over one disk.\n *\n * **Always pass an explicit `alias` in anything re-runnable.** Redeploying\n * the same alias is the in-place update you actually want.\n *\n * ```ts\n * await unfazed.deployBox({ workspaceId: ws.id, alias: \"dev\" }); // re-runnable\n * ```\n */\n deployBox(options: DeployBoxOptions): Promise<Deployment> {\n const { workspaceId, alias, resources } = options;\n return this.#deploy(\n {\n workspaceID: workspaceId,\n kind: \"BOX\",\n ...(alias === undefined ? {} : { alias }),\n ...(resources === undefined ? {} : { boxResources: resources }),\n },\n options,\n );\n }\n\n /** Escape hatch: deploy with a raw CreateDeploymentInput. */\n deploy(\n input: CreateDeploymentInput,\n options: Omit<DeployOptions, \"workspaceId\"> = {},\n ): Promise<Deployment> {\n return this.#deploy(input, options);\n }\n\n async #deploy(\n input: CreateDeploymentInput,\n options: Omit<DeployOptions, \"workspaceId\">,\n ): Promise<Deployment> {\n const requestOptions: RequestOptions = options.signal ? { signal: options.signal } : {};\n const data = await this.client.mutate(ops.CreateDeploymentDocument, { input }, requestOptions);\n const deployment = data.createDeployment.deployment;\n if (!options.wait) return deployment;\n return this.waitForDeployment(deployment.id, {\n ...options.waitOptions,\n ...(options.signal ? { signal: options.signal } : {}),\n });\n }\n\n /**\n * Polls a deployment until it is READY, throwing on FAILED or timeout.\n *\n * BUILDING is the only non-terminal status; READY and FAILED are terminal.\n * The poll query selects six fields rather than the full deployment, because\n * this runs every few seconds for potentially minutes — then the READY\n * deployment is re-read in full so callers get the same shape `deployService`\n * returns without `wait`.\n */\n async waitForDeployment(deploymentId: string, waitOptions: WaitOptions = {}): Promise<Deployment> {\n const resolved = resolveWaitOptions(waitOptions);\n const requestOptions: RequestOptions = resolved.signal ? { signal: resolved.signal } : {};\n let last: { id: string; status: string; error: string | null } | null = null;\n\n await pollWithBackoff<true>(\n async () => {\n const data = await this.client.query(\n ops.PollDeploymentDocument,\n { id: deploymentId },\n requestOptions,\n );\n const d = data.deployment;\n if (!d) {\n throw new UnfazedNotFoundError(`unfazed: deployment ${deploymentId} not found`);\n }\n last = d;\n if (d.status === \"READY\") return { done: true, value: true };\n if (d.status === \"FAILED\") {\n throw new UnfazedDeployError(\n \"FAILED\",\n deploymentId,\n d,\n `unfazed: deployment ${deploymentId} FAILED${d.error ? `: ${d.error}` : \"\"}`,\n );\n }\n return { done: false };\n },\n resolved,\n () =>\n new UnfazedDeployError(\n \"TIMEOUT\",\n deploymentId,\n last,\n `unfazed: deployment ${deploymentId} still ${\n (last as { status?: string } | null)?.status ?? \"BUILDING\"\n } after ${resolved.timeoutMs}ms`,\n ),\n );\n\n const full = await this.getDeployment(deploymentId, requestOptions);\n if (!full) throw new UnfazedNotFoundError(`unfazed: deployment ${deploymentId} not found`);\n return full;\n }\n\n /** Reads one deployment by id. Null when absent. */\n async getDeployment(\n deploymentId: string,\n options?: RequestOptions,\n ): Promise<Deployment | null> {\n const data = await this.client.query(ops.GetDeploymentDocument, { id: deploymentId }, options);\n return data.deployment;\n }\n\n /** Reads the deployment currently serving an alias. Null when absent. */\n async getDeploymentByAlias(\n alias: string,\n options?: RequestOptions,\n ): Promise<Deployment | null> {\n const data = await this.client.query(ops.GetDeploymentByAliasDocument, { alias }, options);\n return data.deploymentByAlias;\n }\n\n /** Lists deployments (paginated, filterable by kind/alias/workspace). */\n async listDeployments(input: ListDeploymentsInput = {}, options?: RequestOptions) {\n const data = await this.client.query(ops.ListDeploymentsDocument, { input }, options);\n return data.deploymentsPage;\n }\n\n /* ------------------------------------------------------- runtime & logging */\n\n /** Live VM status: health, in-flight requests, restarts, RAM ceiling. */\n async getStatus(deploymentId: string, options?: RequestOptions) {\n const data = await this.client.query(\n ops.ServiceStatusDocument,\n { deploymentID: deploymentId },\n options,\n );\n return data.serviceStatus;\n }\n\n /**\n * Tail of the service's stdout/stderr.\n *\n * The point of doing this from a script rather than through tool calls: you\n * can filter locally. `(await unfazed.getLogs(id)).stderr.split(\"\\n\")\n * .filter(l => l.includes(\"ERROR\"))` costs a model zero context, where the\n * same tail through an MCP tool spends all of it.\n */\n async getLogs(\n deploymentId: string,\n input: { tailBytes?: number } = {},\n options?: RequestOptions,\n ) {\n const data = await this.client.query(\n ops.ServiceLogsDocument,\n { deploymentID: deploymentId, tailBytes: input.tailBytes ?? null },\n options,\n );\n return data.serviceLogs;\n }\n\n /** Deployment lifecycle events — build, boot, probe, cron, restarts. */\n async getEvents(deploymentId: string, limit?: number, options?: RequestOptions) {\n const data = await this.client.query(\n ops.DeploymentEventsDocument,\n { deploymentID: deploymentId, limit: limit ?? null },\n options,\n );\n return data.deploymentEvents;\n }\n\n /** Restarts a service's VM. */\n async restartService(deploymentId: string, options?: RequestOptions) {\n const data = await this.client.mutate(\n ops.RestartServiceDocument,\n { deploymentID: deploymentId },\n options,\n );\n return data.restartService;\n }\n\n /** Stops a service's VM. An on-demand service cold-starts again on request. */\n async stopService(deploymentId: string, options?: RequestOptions) {\n const data = await this.client.mutate(\n ops.StopServiceDocument,\n { deploymentID: deploymentId },\n options,\n );\n return data.stopService;\n }\n\n /**\n * Deletes a deployment: stops its VM, releases its alias, drops its release.\n *\n * With `ignoreNotFound` a deployment that is absent — or belongs to another\n * tenant, which the server reports identically so ids cannot be probed —\n * resolves to `false` instead of throwing, making cleanup loops idempotent.\n */\n async deleteDeployment(\n deploymentId: string,\n options: DeleteDeploymentOptions = {},\n ): Promise<boolean> {\n try {\n const data = await this.client.mutate(\n ops.DeleteDeploymentDocument,\n { deploymentID: deploymentId },\n options,\n );\n return data.deleteDeployment.ok;\n } catch (e) {\n if (options.ignoreNotFound && isNotFound(e, DEPLOYMENT_NOT_FOUND)) return false;\n throw e;\n }\n }\n\n /* ------------------------------------------------------------ env & secrets\n *\n * Workspace values are SERVICE defaults for every app in the source; app\n * values override them for one alias. Both are SNAPSHOTTED into a release at\n * deploy time — changing either does not affect a running app until you\n * redeploy that alias. Old releases are immutable, and STATIC gets no env.\n */\n\n /**\n * Sets a workspace-default env var. Redeploy the alias to apply it.\n *\n * A name is either plain or secret, never both: this DELETES a workspace\n * secret of the same name. {@link setSecret} displaces a plain var the same\n * way. Last write wins, and the kind flips silently — so re-running a setup\n * script that calls `setSecret(\"API_KEY\", ...)` after one that called\n * `setEnv(\"API_KEY\", ...)` quietly converts it, and vice versa.\n */\n async setEnv(\n workspaceId: string,\n name: string,\n value: string,\n options?: RequestOptions,\n ): Promise<EnvVar> {\n const data = await this.client.mutate(\n ops.SetWorkspaceEnvDocument,\n { workspaceID: workspaceId, name, value },\n options,\n );\n return data.setWorkspaceEnv.env;\n }\n\n /**\n * Sets a workspace-default secret. The value is never readable again.\n *\n * Mutually exclusive with {@link setEnv}: this DELETES a plain workspace var\n * of the same name. See {@link setEnv} for the displacement rule.\n */\n async setSecret(\n workspaceId: string,\n name: string,\n value: string,\n options?: RequestOptions,\n ): Promise<EnvVar> {\n const data = await this.client.mutate(\n ops.SetWorkspaceSecretDocument,\n { workspaceID: workspaceId, name, value },\n options,\n );\n return data.setWorkspaceSecret.env;\n }\n\n /**\n * Sets many workspace env vars in one request, via aliased mutations —\n * the same batching trick as {@link writeFiles}.\n *\n * Pass `{ secret: true }` to route them all to `setWorkspaceSecret`.\n *\n * It inherits {@link writeFiles}' failure semantics too: the batch is NOT\n * atomic. GraphQL resolves each aliased field independently, so a rejected\n * name (over the limit, malformed, whatever) leaves the vars before it\n * already committed. The thrown {@link UnfazedGraphQLError} carries `data`\n * with the aliases that succeeded and `errors[].path` naming those that did\n * not — do not assume \"it threw\" means \"nothing was written\".\n *\n * Each name still displaces its opposite kind, exactly as {@link setEnv} and\n * {@link setSecret} do one at a time.\n */\n async setEnvMany(\n workspaceId: string,\n vars: Record<string, string>,\n options: { secret?: boolean; signal?: AbortSignal } = {},\n ): Promise<EnvVar[]> {\n const entries = Object.entries(vars);\n if (entries.length === 0) return [];\n\n const field = options.secret ? \"setWorkspaceSecret\" : \"setWorkspaceEnv\";\n const varDefs = [\"$workspaceID: ID!\"];\n const fields: string[] = [];\n const variables: Record<string, string> = { workspaceID: workspaceId };\n\n entries.forEach(([name, value], i) => {\n varDefs.push(`$n${i}: String!`, `$v${i}: String!`);\n variables[`n${i}`] = name;\n variables[`v${i}`] = value;\n fields.push(\n ` e${i}: ${field}(input: { workspaceID: $workspaceID, name: $n${i}, value: $v${i} }) { env { ${ENV_SELECTION} } }`,\n );\n });\n\n const document = `mutation SdkSetEnvBatch(${varDefs.join(\", \")}) {\\n${fields.join(\"\\n\")}\\n}`;\n const data = await this.client.mutate<Record<string, { env: EnvVar }>, typeof variables>(\n document,\n variables,\n options.signal ? { signal: options.signal } : {},\n );\n return entries.map((_, i) => data[`e${i}`]!.env);\n }\n\n /**\n * Deletes a workspace-default env var (plain or secret).\n *\n * **The `ok: false` convention.** A `false` here does NOT mean failure — it\n * means \"nothing to do, the world is already in the state you asked for\".\n * The var did not exist. Every `ok`-returning mutation in this SDK follows\n * the rule ({@link deleteFile}, {@link inheritAppEnv}, {@link removeAppEnv}),\n * so the idempotent-cleanup pattern is simply to ignore the boolean; a real\n * failure throws.\n */\n async deleteEnv(workspaceId: string, name: string, options?: RequestOptions): Promise<boolean> {\n const data = await this.client.mutate(\n ops.DeleteWorkspaceEnvDocument,\n { workspaceID: workspaceId, name },\n options,\n );\n return data.deleteWorkspaceEnv.ok;\n }\n\n /** Workspace-default env vars. Secret values are redacted. */\n async listEnv(workspaceId: string, options?: RequestOptions): Promise<EnvVar[]> {\n const data = await this.client.query(\n ops.ListWorkspaceEnvDocument,\n { workspaceID: workspaceId },\n options,\n );\n return data.workspaceEnv;\n }\n\n /**\n * Sets an env var for ONE alias, overriding the workspace default.\n *\n * Displaces both of the other states this name could be in for the app: it\n * deletes an app SECRET of the same name, and it CLEARS a REMOVE mask left\n * by {@link removeAppEnv}. So setting a value is also the way to un-block a\n * masked name, and a name is only ever one of plain / secret / masked.\n */\n async setAppEnv(\n workspaceId: string,\n alias: string,\n name: string,\n value: string,\n options?: RequestOptions,\n ): Promise<EnvVar> {\n const data = await this.client.mutate(\n ops.SetAppEnvDocument,\n { workspaceID: workspaceId, alias, name, value },\n options,\n );\n return data.setAppEnv.env;\n }\n\n /**\n * Sets a secret for ONE alias, overriding the workspace default.\n *\n * Like {@link setAppEnv}, this deletes a plain app var of the same name and\n * clears a REMOVE mask for it.\n */\n async setAppSecret(\n workspaceId: string,\n alias: string,\n name: string,\n value: string,\n options?: RequestOptions,\n ): Promise<EnvVar> {\n const data = await this.client.mutate(\n ops.SetAppSecretDocument,\n { workspaceID: workspaceId, alias, name, value },\n options,\n );\n return data.setAppSecret.env;\n }\n\n /**\n * REMOVE: blocks this name for the app entirely — the app override, the\n * workspace default, and integration enrichment. Not the same as deleting an\n * override; use {@link inheritAppEnv} for that.\n *\n * This WRITES A MASK, and the mask is a real, persistent row. Two things\n * follow that surprise people:\n *\n * - It is written even when nothing was inherited. Masking a name that no\n * workspace default and no integration ever provided is not a no-op; it\n * leaves a tombstone that keeps blocking the name if a default appears\n * later. Clear it with {@link inheritAppEnv}.\n * - It COSTS A SLOT. A workspace gets 128 env entries total — that budget\n * is shared across the workspace defaults AND every app scope combined,\n * not 128 per scope — and masks count toward it just like values do.\n * Masking names in a loop can exhaust the workspace's env budget.\n *\n * Returns `false` when the exact mask was already present (a second call for\n * the same name), per the {@link deleteEnv} `ok: false` convention. It\n * returns `true` when it had something to change — including converting an\n * existing override into a mask.\n */\n async removeAppEnv(\n workspaceId: string,\n alias: string,\n name: string,\n options?: RequestOptions,\n ): Promise<boolean> {\n const data = await this.client.mutate(\n ops.RemoveAppEnvDocument,\n { workspaceID: workspaceId, alias, name },\n options,\n );\n return data.removeAppEnv.ok;\n }\n\n /**\n * INHERIT: clears the app override/mask so workspace and integration values\n * apply again. This is the undo for both {@link setAppEnv} and\n * {@link removeAppEnv}.\n *\n * Returns `false` when there was no override and no mask to clear — nothing\n * to do, not a failure. See {@link deleteEnv}.\n */\n async inheritAppEnv(\n workspaceId: string,\n alias: string,\n name: string,\n options?: RequestOptions,\n ): Promise<boolean> {\n const data = await this.client.mutate(\n ops.InheritAppEnvDocument,\n { workspaceID: workspaceId, alias, name },\n options,\n );\n return data.inheritAppEnv.ok;\n }\n\n /** The effective env view for one alias: overrides, inherited and masked. */\n async listAppEnv(\n workspaceId: string,\n alias: string,\n options?: RequestOptions,\n ): Promise<EnvVar[]> {\n const data = await this.client.query(\n ops.ListAppEnvDocument,\n { workspaceID: workspaceId, alias },\n options,\n );\n return data.appEnv;\n }\n\n /* -------------------------------------------------- releases & rollback */\n\n /**\n * An alias's terminal release history, newest first.\n *\n * Exactly one entry has `aliasHeld: true` — the live release. FAILED entries\n * appear on purpose (they are rejected promotions, so a kept-live previous\n * release is never mistaken for a silent fallback) and cannot be rolled back\n * to. Retention keeps only the most recent few per alias, default 5.\n */\n async listReleases(alias: string, options?: RequestOptions): Promise<Deployment[]> {\n const data = await this.client.query(ops.ListReleasesDocument, { alias }, options);\n return data.deploymentReleases;\n }\n\n /**\n * Rolls an alias back to a prior release, handling the whole compare-and-swap\n * protocol in one call.\n *\n * The server requires the caller to prove it observed the current state: you\n * must pass the live release's id AND its opaque `aliasRevision`, and the\n * swap fails if either changed since you listed — including same-id ABA. So\n * this method does the full dance: list releases, find the `aliasHeld` entry,\n * pick the target, and submit both guard values.\n *\n * On a rejected guard it re-lists and retries (default once). The TARGET is\n * pinned across retries while the guard is refreshed, so a concurrent deploy\n * can never redirect the rollback to a different release than the one chosen.\n *\n * ```ts\n * await unfazed.rollback({ alias: \"my-app\" }); // undo last deploy\n * await unfazed.rollback({ alias: \"my-app\", to: relId }); // to a specific release\n * await unfazed.rollback({ alias: \"my-app\", to: relId, expectedCurrentId: liveId });\n * ```\n *\n * ⚠️ **A bare `rollback({ alias })` is a TOGGLE, not an idempotent step.**\n * It means \"restore the most recent READY release that is not the live one\",\n * which is a different release each time the alias moves. Run the same\n * script twice and the second run rolls back the rollback — A → B → A → B,\n * forever, with each hop a real alias swap. Nothing errors, because every\n * individual call did exactly what it was asked.\n *\n * In anything re-runnable — a retry loop, a CI job, an agent that might redo\n * a step — pin the outcome instead:\n *\n * - `to:` names the release you want live, so re-running is a no-op-ish\n * convergence rather than a flip (a second run then reports the target\n * already holds the alias instead of moving it);\n * - `expectedCurrentId:` states what you expect to be live now, so a second\n * run fails loudly instead of silently undoing the first.\n */\n async rollback(options: RollbackOptions): Promise<Deployment> {\n const { alias, signal, expectedCurrentId } = options;\n // A caller-supplied precondition and the CAS retry are mutually exclusive:\n // retrying re-guards against whatever holds the alias NOW, which is the\n // one thing `expectedCurrentId` exists to refuse.\n const retries = expectedCurrentId === undefined ? (options.retries ?? 1) : 0;\n const requestOptions: RequestOptions = signal ? { signal } : {};\n\n let targetId = options.to;\n\n for (let attempt = 0; ; attempt++) {\n const releases = await this.listReleases(alias, requestOptions);\n if (releases.length === 0) {\n throw new UnfazedNotFoundError(`unfazed: alias \"${alias}\" has no release history`);\n }\n\n const current = releases.find((r) => r.aliasHeld);\n if (!current) {\n throw new UnfazedNotFoundError(\n `unfazed: alias \"${alias}\" has no current release holding the alias`,\n );\n }\n\n // The caller's precondition, checked before anything is sent. Failing\n // here rather than at the server keeps a violated expectation from\n // costing an alias swap, and reports the holder we actually observed.\n if (expectedCurrentId !== undefined && current.id !== expectedCurrentId) {\n throw new UnfazedConflictError(\n `unfazed: alias \"${alias}\" is held by ${current.id}, not the expected ` +\n `${expectedCurrentId} — it moved since you read it; re-read and decide again`,\n [],\n );\n }\n\n // Pin the target on the first pass so a retry refreshes only the guard.\n if (targetId === undefined) {\n const previous = releases.find((r) => r.id !== current.id && r.status === \"READY\");\n if (!previous) {\n throw new UnfazedNotFoundError(\n `unfazed: alias \"${alias}\" has no prior READY release to roll back to ` +\n `(history: ${releases.map((r) => `${r.id}:${r.status}`).join(\", \")})`,\n );\n }\n targetId = previous.id;\n }\n\n const target = releases.find((r) => r.id === targetId);\n if (!target) {\n throw new UnfazedNotFoundError(\n `unfazed: release ${targetId} is not in alias \"${alias}\"'s history ` +\n `(it may have been pruned; retention keeps only the most recent few)`,\n );\n }\n if (target.id === current.id) {\n throw new UnfazedConflictError(\n `unfazed: release ${targetId} already holds alias \"${alias}\"`,\n [],\n );\n }\n if (target.status !== \"READY\") {\n throw new UnfazedConflictError(\n `unfazed: release ${targetId} is ${target.status}, only READY releases can be restored`,\n [],\n );\n }\n\n try {\n const data = await this.client.mutate(\n ops.RollbackDocument,\n {\n deploymentID: target.id,\n expectedCurrentDeploymentID: current.id,\n expectedCurrentAliasRevision: current.aliasRevision,\n },\n requestOptions,\n );\n return data.rollbackDeployment;\n } catch (e) {\n const retryable =\n e instanceof UnfazedGraphQLError && looksLikeCASConflict(e.errors) && attempt < retries;\n if (!retryable) {\n if (e instanceof UnfazedGraphQLError && looksLikeCASConflict(e.errors)) {\n throw new UnfazedConflictError(\n `unfazed: rollback of \"${alias}\" lost the compare-and-swap after ${\n attempt + 1\n } attempt(s) — the alias is being deployed concurrently. ${e.message}`,\n e.errors,\n );\n }\n throw e;\n }\n // Loop: re-list, rebuild the guard, keep the same target.\n }\n }\n }\n\n /* -------------------------------------------------------------- internals */\n\n /**\n * Finds a visible workspace by name, the way the server compares names.\n *\n * The server rejects duplicates with Go's `strings.EqualFold`, so matching\n * must be case-insensitive here too or `ensureWorkspace` would try to create\n * a \"new\" workspace the server considers a duplicate. An exact-case hit wins\n * over a folded one, which only matters if a name ever slipped past the\n * uniqueness check.\n */\n async #findWorkspaceByName(\n name: string,\n options?: RequestOptions,\n ): Promise<Workspace | undefined> {\n const workspaces = await this.listWorkspaces(options);\n const folded = name.toLowerCase();\n return (\n workspaces.find((w) => w.name === name) ??\n workspaces.find((w) => w.name.toLowerCase() === folded)\n );\n }\n\n async #writeBatch(\n workspaceId: string,\n batch: NormalizedFile[],\n signal?: AbortSignal,\n ): Promise<WorkspaceFile[]> {\n const varDefs = [\"$workspaceID: ID!\"];\n const fields: string[] = [];\n const variables: Record<string, string> = { workspaceID: workspaceId };\n\n batch.forEach((file, i) => {\n variables[`p${i}`] = file.path;\n variables[`c${i}`] = file.content;\n varDefs.push(`$p${i}: String!`, `$c${i}: String!`);\n fields.push(\n file.kind === \"text\"\n ? ` f${i}: writeWorkspaceTextFile(input: { workspaceID: $workspaceID, path: $p${i}, text: $c${i} }) { file { ${FILE_SELECTION} } }`\n : ` f${i}: writeWorkspaceBase64File(input: { workspaceID: $workspaceID, path: $p${i}, contentBase64: $c${i} }) { file { ${FILE_SELECTION} } }`,\n );\n });\n\n // Built at runtime rather than codegen'd: the field COUNT varies per call,\n // so no static document can express it. The field shapes are still fixed\n // and typed below, and each individual mutation is codegen-validated by its\n // single-file twin in operations.ts.\n const document = `mutation SdkWriteFilesBatch(${varDefs.join(\", \")}) {\\n${fields.join(\"\\n\")}\\n}`;\n\n const data = await this.client.mutate<\n Record<string, { file: WorkspaceFile }>,\n typeof variables\n >(document, variables, signal ? { signal } : {});\n\n return batch.map((_, i) => data[`f${i}`]!.file);\n }\n}\n\nconst FILE_SELECTION = \"path sizeBytes size sha256 updatedAt\";\nconst ENV_SELECTION = \"name value secret alias inherited masked updatedAt\";\n\ninterface NormalizedFile {\n path: string;\n kind: \"text\" | \"base64\";\n content: string;\n}\n\nfunction normalizeFile(path: string, content: FileContent): NormalizedFile {\n if (typeof content === \"string\") return { path, kind: \"text\", content };\n if (\"text\" in content) return { path, kind: \"text\", content: content.text };\n if (\"base64\" in content) return { path, kind: \"base64\", content: content.base64 };\n return { path, kind: \"base64\", content: toBase64(content.bytes) };\n}\n\nfunction toBase64(input: Uint8Array | ArrayBuffer): string {\n const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);\n // Node/Bun have Buffer; browsers and workers do not.\n const maybeBuffer = (globalThis as { Buffer?: { from(b: Uint8Array): { toString(e: string): string } } })\n .Buffer;\n if (maybeBuffer) return maybeBuffer.from(bytes).toString(\"base64\");\n\n let binary = \"\";\n const CHUNK = 0x8000; // avoid blowing the argument limit on large files\n for (let i = 0; i < bytes.length; i += CHUNK) {\n binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));\n }\n return btoa(binary);\n}\n\nconst utf8 = new TextEncoder();\n\n/**\n * UTF-8 byte length, which is what the wire actually costs.\n *\n * `String.length` counts UTF-16 code units and undercounts by up to 3x on\n * non-ASCII text — a CJK or emoji-heavy payload would sail past a budget it\n * had already blown.\n */\nfunction utf8Bytes(s: string): number {\n return utf8.encode(s).length;\n}\n\n/**\n * Splits files into request-sized batches.\n *\n * Closes a batch on whichever limit trips first — count or bytes — but always\n * emits at least one file per batch, so a single file larger than\n * `maxBatchBytes` still gets sent (and fails loudly at the server's limit)\n * rather than silently vanishing into an empty batch.\n */\nfunction chunkFiles(\n files: NormalizedFile[],\n batchSize: number,\n maxBatchBytes: number,\n): NormalizedFile[][] {\n const batches: NormalizedFile[][] = [];\n let current: NormalizedFile[] = [];\n let bytes = 0;\n\n for (const file of files) {\n // Measured once per file, so the encode cost is linear in the payload the\n // request was going to carry anyway.\n const size = utf8Bytes(file.content) + utf8Bytes(file.path);\n if (current.length > 0 && (current.length >= batchSize || bytes + size > maxBatchBytes)) {\n batches.push(current);\n current = [];\n bytes = 0;\n }\n current.push(file);\n bytes += size;\n }\n if (current.length > 0) batches.push(current);\n return batches;\n}\n"]}
package/dist/wait.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Knobs for any polling wait.
3
+ *
4
+ * `sleep` and `now` are injectable so the test suite can drive multi-minute
5
+ * backoff schedules instantly and assert the exact interval sequence, instead
6
+ * of actually waiting. Production code never passes them.
7
+ */
8
+ export interface WaitOptions {
9
+ /**
10
+ * Give up after this long. Default 600_000 (10 minutes) — a cold Bun build
11
+ * plus VM boot and health probe routinely runs into minutes, and the build
12
+ * microVM's own ceiling is 600s.
13
+ */
14
+ timeoutMs?: number;
15
+ /** First poll delay in ms. Default 1_000. */
16
+ initialIntervalMs?: number;
17
+ /** Ceiling for the backoff in ms. Default 10_000. */
18
+ maxIntervalMs?: number;
19
+ /** Backoff multiplier. Default 1.5. */
20
+ factor?: number;
21
+ /** Cancels the wait; surfaces as {@link UnfazedTimeoutError}. */
22
+ signal?: AbortSignal;
23
+ /** Injected clock (tests). */
24
+ now?: () => number;
25
+ /** Injected sleep (tests). */
26
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
27
+ }
28
+ export interface ResolvedWaitOptions {
29
+ timeoutMs: number;
30
+ initialIntervalMs: number;
31
+ maxIntervalMs: number;
32
+ factor: number;
33
+ signal: AbortSignal | undefined;
34
+ now: () => number;
35
+ sleep: (ms: number, signal?: AbortSignal) => Promise<void>;
36
+ }
37
+ export declare function resolveWaitOptions(options?: WaitOptions): ResolvedWaitOptions;
38
+ /** What one poll tick decided. */
39
+ export type PollDecision<T> = {
40
+ done: true;
41
+ value: T;
42
+ } | {
43
+ done: false;
44
+ };
45
+ /**
46
+ * Generic exponential-backoff poll loop.
47
+ *
48
+ * Polls immediately (no initial sleep — most callers have just created the
49
+ * thing and a first read is nearly free), then backs off geometrically up to
50
+ * `maxIntervalMs`. The final sleep is clamped so the loop cannot overshoot
51
+ * `timeoutMs`, which keeps `wait: true` honest as a deadline rather than a
52
+ * suggestion.
53
+ *
54
+ * `onTimeout` builds the error so callers can attach their own context (the
55
+ * last deployment snapshot, say) instead of getting a bare timeout.
56
+ */
57
+ export declare function pollWithBackoff<T>(poll: () => Promise<PollDecision<T>>, options: ResolvedWaitOptions, onTimeout: () => Error): Promise<T>;
package/dist/wait.js ADDED
@@ -0,0 +1,59 @@
1
+ import { UnfazedTimeoutError } from "./errors.js";
2
+ export function resolveWaitOptions(options = {}) {
3
+ return {
4
+ timeoutMs: options.timeoutMs ?? 600_000,
5
+ initialIntervalMs: options.initialIntervalMs ?? 1_000,
6
+ maxIntervalMs: options.maxIntervalMs ?? 10_000,
7
+ factor: options.factor ?? 1.5,
8
+ signal: options.signal,
9
+ now: options.now ?? (() => Date.now()),
10
+ sleep: options.sleep ?? defaultSleep,
11
+ };
12
+ }
13
+ function defaultSleep(ms, signal) {
14
+ return new Promise((resolve, reject) => {
15
+ if (signal?.aborted) {
16
+ reject(new UnfazedTimeoutError("unfazed: wait aborted"));
17
+ return;
18
+ }
19
+ const timer = setTimeout(() => {
20
+ signal?.removeEventListener("abort", onAbort);
21
+ resolve();
22
+ }, ms);
23
+ const onAbort = () => {
24
+ clearTimeout(timer);
25
+ reject(new UnfazedTimeoutError("unfazed: wait aborted"));
26
+ };
27
+ signal?.addEventListener("abort", onAbort, { once: true });
28
+ });
29
+ }
30
+ /**
31
+ * Generic exponential-backoff poll loop.
32
+ *
33
+ * Polls immediately (no initial sleep — most callers have just created the
34
+ * thing and a first read is nearly free), then backs off geometrically up to
35
+ * `maxIntervalMs`. The final sleep is clamped so the loop cannot overshoot
36
+ * `timeoutMs`, which keeps `wait: true` honest as a deadline rather than a
37
+ * suggestion.
38
+ *
39
+ * `onTimeout` builds the error so callers can attach their own context (the
40
+ * last deployment snapshot, say) instead of getting a bare timeout.
41
+ */
42
+ export async function pollWithBackoff(poll, options, onTimeout) {
43
+ const { timeoutMs, initialIntervalMs, maxIntervalMs, factor, signal, now, sleep } = options;
44
+ const deadline = now() + timeoutMs;
45
+ let interval = initialIntervalMs;
46
+ for (;;) {
47
+ if (signal?.aborted)
48
+ throw new UnfazedTimeoutError("unfazed: wait aborted");
49
+ const decision = await poll();
50
+ if (decision.done)
51
+ return decision.value;
52
+ const remaining = deadline - now();
53
+ if (remaining <= 0)
54
+ throw onTimeout();
55
+ await sleep(Math.min(interval, remaining), signal);
56
+ interval = Math.min(interval * factor, maxIntervalMs);
57
+ }
58
+ }
59
+ //# sourceMappingURL=wait.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.js","sourceRoot":"","sources":["../src/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAwClD,MAAM,UAAU,kBAAkB,CAAC,UAAuB,EAAE;IAC1D,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO;QACvC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,KAAK;QACrD,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,MAAM;QAC9C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,GAAG;QAC7B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,YAAY;KACrC,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,EAAU,EAAE,MAAoB;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,mBAAmB,CAAC,uBAAuB,CAAC,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,mBAAmB,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC;QACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAKD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAoC,EACpC,OAA4B,EAC5B,SAAsB;IAEtB,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC5F,MAAM,QAAQ,GAAG,GAAG,EAAE,GAAG,SAAS,CAAC;IACnC,IAAI,QAAQ,GAAG,iBAAiB,CAAC;IAEjC,SAAS,CAAC;QACR,IAAI,MAAM,EAAE,OAAO;YAAE,MAAM,IAAI,mBAAmB,CAAC,uBAAuB,CAAC,CAAC;QAE5E,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,CAAC;QAC9B,IAAI,QAAQ,CAAC,IAAI;YAAE,OAAO,QAAQ,CAAC,KAAK,CAAC;QAEzC,MAAM,SAAS,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC;QACnC,IAAI,SAAS,IAAI,CAAC;YAAE,MAAM,SAAS,EAAE,CAAC;QAEtC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QACnD,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,MAAM,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;AACH,CAAC","sourcesContent":["import { UnfazedTimeoutError } from \"./errors.js\";\n\n/**\n * Knobs for any polling wait.\n *\n * `sleep` and `now` are injectable so the test suite can drive multi-minute\n * backoff schedules instantly and assert the exact interval sequence, instead\n * of actually waiting. Production code never passes them.\n */\nexport interface WaitOptions {\n /**\n * Give up after this long. Default 600_000 (10 minutes) — a cold Bun build\n * plus VM boot and health probe routinely runs into minutes, and the build\n * microVM's own ceiling is 600s.\n */\n timeoutMs?: number;\n /** First poll delay in ms. Default 1_000. */\n initialIntervalMs?: number;\n /** Ceiling for the backoff in ms. Default 10_000. */\n maxIntervalMs?: number;\n /** Backoff multiplier. Default 1.5. */\n factor?: number;\n /** Cancels the wait; surfaces as {@link UnfazedTimeoutError}. */\n signal?: AbortSignal;\n /** Injected clock (tests). */\n now?: () => number;\n /** Injected sleep (tests). */\n sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n}\n\nexport interface ResolvedWaitOptions {\n timeoutMs: number;\n initialIntervalMs: number;\n maxIntervalMs: number;\n factor: number;\n signal: AbortSignal | undefined;\n now: () => number;\n sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n}\n\nexport function resolveWaitOptions(options: WaitOptions = {}): ResolvedWaitOptions {\n return {\n timeoutMs: options.timeoutMs ?? 600_000,\n initialIntervalMs: options.initialIntervalMs ?? 1_000,\n maxIntervalMs: options.maxIntervalMs ?? 10_000,\n factor: options.factor ?? 1.5,\n signal: options.signal,\n now: options.now ?? (() => Date.now()),\n sleep: options.sleep ?? defaultSleep,\n };\n}\n\nfunction defaultSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new UnfazedTimeoutError(\"unfazed: wait aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n reject(new UnfazedTimeoutError(\"unfazed: wait aborted\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\n/** What one poll tick decided. */\nexport type PollDecision<T> = { done: true; value: T } | { done: false };\n\n/**\n * Generic exponential-backoff poll loop.\n *\n * Polls immediately (no initial sleep — most callers have just created the\n * thing and a first read is nearly free), then backs off geometrically up to\n * `maxIntervalMs`. The final sleep is clamped so the loop cannot overshoot\n * `timeoutMs`, which keeps `wait: true` honest as a deadline rather than a\n * suggestion.\n *\n * `onTimeout` builds the error so callers can attach their own context (the\n * last deployment snapshot, say) instead of getting a bare timeout.\n */\nexport async function pollWithBackoff<T>(\n poll: () => Promise<PollDecision<T>>,\n options: ResolvedWaitOptions,\n onTimeout: () => Error,\n): Promise<T> {\n const { timeoutMs, initialIntervalMs, maxIntervalMs, factor, signal, now, sleep } = options;\n const deadline = now() + timeoutMs;\n let interval = initialIntervalMs;\n\n for (;;) {\n if (signal?.aborted) throw new UnfazedTimeoutError(\"unfazed: wait aborted\");\n\n const decision = await poll();\n if (decision.done) return decision.value;\n\n const remaining = deadline - now();\n if (remaining <= 0) throw onTimeout();\n\n await sleep(Math.min(interval, remaining), signal);\n interval = Math.min(interval * factor, maxIntervalMs);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,25 +1,69 @@
1
1
  {
2
2
  "name": "unfazed",
3
- "version": "0.0.1",
4
- "description": "Placeholder for the unfazed package. Under active development — not ready for use.",
3
+ "version": "0.2.0",
4
+ "description": "Official TypeScript SDK for unfazed. The code-mode companion to the unfazed MCP server: deploy, wait, tail logs and roll back from one script.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
- "main": "./index.js",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
8
10
  "exports": {
9
- ".": "./index.js"
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json"
10
17
  },
11
18
  "files": [
12
- "index.js"
19
+ "dist",
20
+ "schema/schema.graphqls",
21
+ "schema/SOURCE.json",
22
+ "README.md",
23
+ "LICENSE"
13
24
  ],
25
+ "sideEffects": false,
26
+ "engines": {
27
+ "bun": ">=1.2",
28
+ "node": ">=20"
29
+ },
14
30
  "keywords": [
15
- "unfazed"
31
+ "unfazed",
32
+ "deploy",
33
+ "deployment",
34
+ "graphql",
35
+ "sdk",
36
+ "agents",
37
+ "code-mode",
38
+ "mcp",
39
+ "bun"
16
40
  ],
17
41
  "repository": {
18
42
  "type": "git",
19
43
  "url": "git+https://github.com/jilio/unfazed-packages.git",
20
44
  "directory": "packages/unfazed"
21
45
  },
46
+ "homepage": "https://unfazed.dev",
47
+ "bugs": {
48
+ "url": "https://github.com/jilio/unfazed-packages/issues"
49
+ },
22
50
  "publishConfig": {
23
51
  "access": "public"
52
+ },
53
+ "scripts": {
54
+ "sync-schema": "bun run scripts/sync-schema.ts",
55
+ "codegen": "graphql-codegen --config codegen.ts && bun run scripts/postcodegen.ts",
56
+ "typecheck": "tsc --noEmit",
57
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
58
+ "test": "bun test",
59
+ "smoke": "bun test/smoke-dist.mjs && node test/smoke-dist.mjs",
60
+ "check": "bun run typecheck && bun test && bun run build && bun run smoke"
61
+ },
62
+ "devDependencies": {
63
+ "@graphql-codegen/cli": "^7.1.2",
64
+ "@graphql-codegen/client-preset": "^6.0.1",
65
+ "@types/bun": "^1.3.9",
66
+ "graphql": "^16.14.2",
67
+ "typescript": "^6.0.3"
24
68
  }
25
69
  }
@@ -0,0 +1,9 @@
1
+ {
2
+ "$comment": "Provenance for the vendored copy of graph/schema.graphqls. Written by scripts/sync-schema.ts — do not edit by hand.",
3
+ "repo": "unfazed",
4
+ "path": "graph/schema.graphqls",
5
+ "unfazedCommit": "c7068473bafd49e0f7f8705a53bf1d4b451d855b",
6
+ "schemaLastChangedCommit": "fd278d74ac63bc20c4d5adc274559dd096964dc3",
7
+ "sha256": "508b78d0661ce28c6be5a10625d0d9804846f645bb2b952ae166232645b921ba",
8
+ "syncedAt": "2026-08-27"
9
+ }