UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1 lines • 15.1 kB
{"version":3,"file":"client.cjs","names":["z","WorkspaceVersionManifestSchema","Data"],"sources":["../../../../../../apps/upload/src/client.ts"],"sourcesContent":["import { Data } from \"effect\";\nimport { WorkspaceVersionManifestSchema } from \"every-plugin/version-manifest\";\nimport { z } from \"zod\";\n\nexport const BundleFileSchema = z.object({\n path: z.string().min(1).max(512),\n contentBase64: z.string().min(1),\n});\n\nexport const UploadRequestSchema = z.object({\n account: z.string().min(1),\n gateway: z.string().min(1),\n workspace: z.string().min(1),\n files: z.array(BundleFileSchema).min(1).max(10_000),\n});\n\nexport const UploadResponseSchema = z.object({\n stored: z.number().int(),\n /** files recognized as byte-identical to what the store already holds (SRI metadata match) and skipped */\n unchanged: z.number().int().optional(),\n totalBytes: z.number().int(),\n integrity: z.record(z.string(), z.string()),\n storage: z\n .enum([\"s3\", \"memory\"])\n .optional()\n .describe(\n \"Resolved bundle-storage backend: `s3` (R2/MinIO, persistent) or `memory` (ephemeral — bytes are lost on restart)\",\n ),\n});\n\nconst NamespaceQuerySchema = z.object({\n account: z.string().min(1),\n gateway: z.string().min(1),\n});\n\nexport const ListBundlesQuerySchema = NamespaceQuerySchema.extend({\n workspace: z.string().min(1).optional(),\n});\n\nexport const BundleObjectSummarySchema = z.object({\n key: z.string(),\n size: z.number().int(),\n lastModified: z.string().nullable().optional(),\n});\n\nexport const ListBundlesResultSchema = z.object({\n storage: z.enum([\"s3\", \"memory\"]),\n prefix: z.string(),\n objects: z.array(BundleObjectSummarySchema),\n truncated: z.boolean(),\n});\n\nexport const ListVersionsQuerySchema = NamespaceQuerySchema.extend({\n workspace: z.string().min(1),\n});\n\nexport const VersionSummarySchema = z.object({\n version: z.string().regex(/^[0-9a-f]{16}$/),\n entry: z.string(),\n entryIntegrity: z.string(),\n gitSha: z.string().optional(),\n builtAt: z.string().optional(),\n fileCount: z.number().int().optional(),\n lastModified: z.string().nullable().optional(),\n});\n\nexport const ListVersionsResultSchema = z.object({\n storage: z.enum([\"s3\", \"memory\"]),\n versions: z.array(VersionSummarySchema),\n truncated: z.boolean(),\n});\n\nexport const IntegrityReportQuerySchema = NamespaceQuerySchema.extend({\n workspace: z.string().min(1),\n version: z.string().regex(/^[0-9a-f]{16}$/),\n});\n\nexport const IntegrityReportResultSchema = z.object({\n storage: z.enum([\"s3\", \"memory\"]),\n manifest: WorkspaceVersionManifestSchema,\n /** SRI recompute of the manifest's entry object against `entryIntegrity`;\n * null when the entry object is missing from the store. */\n entryVerified: z.boolean().nullable(),\n});\n\nexport type BundleFile = z.infer<typeof BundleFileSchema>;\nexport type UploadRequest = z.infer<typeof UploadRequestSchema>;\nexport type UploadResponse = z.infer<typeof UploadResponseSchema>;\nexport type ListBundlesQuery = z.infer<typeof ListBundlesQuerySchema>;\nexport type BundleObjectSummary = z.infer<typeof BundleObjectSummarySchema>;\nexport type ListBundlesResult = z.infer<typeof ListBundlesResultSchema>;\nexport type ListVersionsQuery = z.infer<typeof ListVersionsQuerySchema>;\nexport type VersionSummary = z.infer<typeof VersionSummarySchema>;\nexport type ListVersionsResult = z.infer<typeof ListVersionsResultSchema>;\nexport type IntegrityReportQuery = z.infer<typeof IntegrityReportQuerySchema>;\nexport type IntegrityReportResult = z.infer<typeof IntegrityReportResultSchema>;\n\nexport interface UploadClientConfig {\n origin: string;\n apiKey?: string;\n fetchImpl?: typeof fetch;\n}\n\nexport interface UploadClient {\n uploadBundle(input: UploadRequest): Promise<UploadResponse>;\n listBundles(input: ListBundlesQuery): Promise<ListBundlesResult>;\n listVersions(input: ListVersionsQuery): Promise<ListVersionsResult>;\n integrityReport(input: IntegrityReportQuery): Promise<IntegrityReportResult>;\n}\n\nconst STATUS_ATTEMPTS = 3;\nconst TRANSPORT_ATTEMPTS = 5;\n/** 522/524 are Cloudflare's \"connection timed out\"/\"origin exceeded the proxy\n * timeout\" codes — the origin may still have applied the upload, and the\n * server-side SRI dedupe makes a retry idempotent. */\nconst RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504, 522, 524]);\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\nconst backoffMs = (attempt: number) => 1000 * attempt + Math.floor(Math.random() * 500);\n\nclass UploadTransferError extends Data.TaggedError(\"UploadTransferError\")<{\n readonly status: number;\n readonly detail: string;\n readonly note?: string;\n}> {\n constructor(status: number, detail: string, note?: string) {\n super({ status, detail, note });\n }\n\n override get message() {\n return `${this.detail}${this.note ?? \"\"}`;\n }\n\n withNote(note: string) {\n return new UploadTransferError(this.status, this.detail, `${this.note ?? \"\"}${note}`);\n }\n}\n\nfunction describeTransferFailure(status: number, detail: string): string {\n const trimmed = detail.slice(0, 300);\n if (status === 408 || /request timeout|bundle upload timed out/i.test(trimmed)) {\n return `${trimmed} — the serving host timed out the upload; raise BOS_STORAGE_UPLOAD_TIMEOUT_MS there or upload smaller batches (BOS_MAX_BUNDLE_UPLOAD_BYTES)`;\n }\n if (status === 524) {\n return `Cloudflare gave up waiting for the upload service (proxy timeout) — the upload may still have been applied (server-side SRI dedupe makes retries idempotent). Upload smaller batches (BOS_MAX_BUNDLE_UPLOAD_BYTES)`;\n }\n try {\n const parsed = JSON.parse(detail) as { code?: unknown; message?: unknown };\n if (parsed?.code === \"INTERNAL_SERVER_ERROR\" && parsed?.message === \"Internal Server Error\") {\n return `${trimmed} — the host hid the underlying error; check the host logs for the cause`;\n }\n } catch {\n // not a JSON error body\n }\n return trimmed;\n}\n\nasync function requestJson<T>(\n config: UploadClientConfig,\n label: string,\n path: string,\n parse: (value: unknown) => T,\n init?: RequestInit,\n): Promise<T> {\n const fetchImpl = config.fetchImpl ?? fetch;\n const headers: Record<string, string> = { ...(init?.headers as Record<string, string>) };\n if (config.apiKey) headers[\"x-api-key\"] = config.apiKey;\n if (init?.body && !headers[\"content-type\"]) headers[\"content-type\"] = \"application/json\";\n\n let lastError: UploadTransferError | Error | undefined;\n let transportFailures = 0;\n let statusFailures = 0;\n for (let attempt = 1; attempt <= TRANSPORT_ATTEMPTS; attempt++) {\n try {\n const response = await fetchImpl(`${config.origin.replace(/\\/$/, \"\")}${path}`, {\n ...init,\n headers: transportFailures > 0 ? { ...headers, connection: \"close\" } : headers,\n });\n\n if (response.ok) {\n return parse(await response.json());\n }\n\n const detail = await response.text().catch(() => \"\");\n lastError = new UploadTransferError(\n response.status,\n `[upload] ${label} failed: ${response.status} ${describeTransferFailure(response.status, detail)}`,\n );\n if (!RETRYABLE_STATUSES.has(response.status)) break;\n statusFailures += 1;\n if (statusFailures >= STATUS_ATTEMPTS) break;\n } catch (error) {\n transportFailures += 1;\n lastError = new UploadTransferError(\n 0,\n `[upload] ${label} failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (attempt < TRANSPORT_ATTEMPTS) await sleep(backoffMs(attempt));\n }\n\n if (lastError instanceof UploadTransferError && lastError.status === 0) {\n lastError = lastError.withNote(\n \" (Bun fetch note: re-run with fetch verbose diagnostics for detail)\",\n );\n }\n throw lastError ?? new Error(`[upload] ${label} failed`);\n}\n\nconst parseJsonBody = <T>(label: string, schema: { parse: (value: unknown) => T }) => {\n return (response: unknown): T => {\n try {\n return schema.parse(response);\n } catch (error) {\n throw new UploadTransferError(\n 0,\n `[upload] ${label} returned an unexpected payload: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n };\n};\n\nexport function createUploadClient(config: UploadClientConfig): UploadClient {\n return {\n uploadBundle(input) {\n const payload = UploadRequestSchema.parse(input);\n return requestJson(\n config,\n `bundle upload for ${payload.workspace}`,\n \"/api/storage/bundles\",\n parseJsonBody(\"bundle upload\", UploadResponseSchema),\n { method: \"POST\", body: JSON.stringify(payload) },\n );\n },\n\n listBundles(input) {\n const query = new URLSearchParams({ account: input.account, gateway: input.gateway });\n if (input.workspace) query.set(\"workspace\", input.workspace);\n return requestJson(\n config,\n \"bundle listing\",\n `/api/storage/bundles?${query.toString()}`,\n parseJsonBody(\"bundle listing\", ListBundlesResultSchema),\n { method: \"GET\" },\n );\n },\n\n listVersions(input) {\n const query = new URLSearchParams({\n account: input.account,\n gateway: input.gateway,\n workspace: input.workspace,\n });\n return requestJson(\n config,\n \"version listing\",\n `/api/storage/versions?${query.toString()}`,\n parseJsonBody(\"version listing\", ListVersionsResultSchema),\n { method: \"GET\" },\n );\n },\n\n integrityReport(input) {\n const query = new URLSearchParams({\n account: input.account,\n gateway: input.gateway,\n workspace: input.workspace,\n version: input.version,\n });\n return requestJson(\n config,\n \"integrity report\",\n `/api/storage/integrity?${query.toString()}`,\n parseJsonBody(\"integrity report\", IntegrityReportResultSchema),\n { method: \"GET\" },\n );\n },\n };\n}\n"],"mappings":"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"}