@editframe/api 0.40.1-beta.0 → 0.40.3

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.
@@ -46,6 +46,7 @@ const CreateRenderPayload = zod.z.object({
46
46
  metadata: zod.z.record(zod.z.string(), zod.z.string()).optional(),
47
47
  duration_ms: zod.z.number().int().optional(),
48
48
  strategy: zod.z.enum(["v1"]).default("v1").optional(),
49
+ backend: zod.z.enum(["cpu", "gpu"]).default("cpu").optional(),
49
50
  output: RenderOutputConfiguration.default({
50
51
  container: "mp4",
51
52
  video: { codec: "h264" },
@@ -1 +1 @@
1
- {"version":3,"file":"renders.cjs","names":["z","output: RenderOutputConfiguration","assertTypesMatch","CompletionIterator"],"sources":["../../src/resources/renders.ts"],"sourcesContent":["import debug from \"debug\";\nimport { z } from \"zod\";\nimport type { Client } from \"../client.js\";\nimport { CompletionIterator } from \"../ProgressIterator.js\";\nimport { assertTypesMatch } from \"../utils/assertTypesMatch.ts\";\n\nconst log = debug(\"ef:api:renders\");\n\nconst H264Configuration = z.object({\n codec: z.literal(\"h264\"),\n});\n\nconst AACConfiguration = z.object({\n codec: z.literal(\"aac\"),\n});\n\nconst MP4Configuration = z.object({\n container: z.literal(\"mp4\"),\n video: H264Configuration,\n audio: AACConfiguration,\n});\n\nconst JpegConfiguration = z.object({\n container: z.literal(\"jpeg\"),\n quality: z.number().int().min(1).max(100).default(80).optional(),\n});\n\nconst PngConfiguration = z.object({\n container: z.literal(\"png\"),\n compression: z.number().int().min(1).max(100).default(80).optional(),\n transparency: z.boolean().default(false).optional(),\n});\n\nconst WebpConfiguration = z.object({\n container: z.literal(\"webp\"),\n quality: z.number().int().min(1).max(100).default(80).optional(),\n compression: z.number().int().min(0).max(6).default(4).optional(),\n transparency: z.boolean().default(false).optional(),\n});\n\nexport const RenderOutputConfiguration = z.discriminatedUnion(\"container\", [\n MP4Configuration,\n JpegConfiguration,\n PngConfiguration,\n WebpConfiguration,\n]);\n\nexport type RenderOutputConfiguration = z.infer<\n typeof RenderOutputConfiguration\n>;\n\nexport const CreateRenderPayload = z.object({\n md5: z.string().optional(),\n fps: z.number().int().min(1).max(120).default(30).optional(),\n width: z.number().int().min(2).optional(),\n height: z.number().int().min(2).optional(),\n work_slice_ms: z\n .number()\n .int()\n .min(1000)\n .max(10_000)\n .default(4_000)\n .optional(),\n html: z.string().optional(),\n metadata: z.record(z.string(), z.string()).optional(),\n duration_ms: z.number().int().optional(),\n strategy: z.enum([\"v1\"]).default(\"v1\").optional(),\n output: RenderOutputConfiguration.default({\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n }).optional(),\n});\n\nexport const CreateRenderPayloadWithOutput = CreateRenderPayload.extend({\n output: RenderOutputConfiguration,\n});\n\nexport class OutputConfiguration {\n static parse(input?: any) {\n const output = RenderOutputConfiguration.parse(\n input ?? {\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n },\n );\n return new OutputConfiguration(output);\n }\n\n constructor(public readonly output: RenderOutputConfiguration) {}\n\n get isStill() {\n return (\n this.output.container === \"jpeg\" ||\n this.output.container === \"png\" ||\n this.output.container === \"webp\"\n );\n }\n\n get isVideo() {\n return this.output.container === \"mp4\";\n }\n\n get fileExtension() {\n return this.output.container;\n }\n\n get contentType() {\n if (this.isStill) {\n return `image/${this.fileExtension}`;\n }\n return `video/${this.fileExtension}`;\n }\n\n get container() {\n return this.output.container;\n }\n\n get jpegConfig() {\n return this.output.container === \"jpeg\" ? this.output : null;\n }\n\n get pngConfig() {\n return this.output.container === \"png\" ? this.output : null;\n }\n\n get webpConfig() {\n return this.output.container === \"webp\" ? this.output : null;\n }\n\n get mp4Config() {\n return this.output.container === \"mp4\" ? this.output : null;\n }\n}\n\nexport interface CreateRenderPayload {\n md5?: string;\n fps?: number;\n width?: number;\n height?: number;\n work_slice_ms?: number;\n html?: string;\n duration_ms?: number;\n metadata?: Record<string, string>;\n strategy?: \"v1\";\n output?: z.infer<typeof RenderOutputConfiguration>;\n}\n\nassertTypesMatch<CreateRenderPayload, z.infer<typeof CreateRenderPayload>>(\n true,\n);\n\nexport interface CreateRenderResult {\n id: string;\n md5: string | null;\n status: \"complete\" | \"created\" | \"failed\" | \"pending\" | \"rendering\" | string;\n metadata: Record<string, string>;\n}\n\nexport interface LookupRenderByMd5Result {\n id: string;\n md5: string | null;\n status: \"complete\" | \"created\" | \"failed\" | \"pending\" | \"rendering\" | string;\n metadata: Record<string, string>;\n}\n\nexport const createRender = async (\n client: Client,\n payload: CreateRenderPayload,\n) => {\n log(\"Creating render\", payload);\n // FIXME: The order of optional/default matters in zod\n // And if we set the default last, the type is not inferred correctly\n // Manually applying defaults here is a hack\n payload.strategy ??= \"v1\";\n payload.work_slice_ms ??= 4_000;\n payload.output ??= {\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n };\n\n const response = await client.authenticatedFetch(\"/api/v1/renders\", {\n method: \"POST\",\n body: JSON.stringify(payload),\n });\n\n log(\"Render created\", response);\n if (response.ok) {\n return (await response.json()) as CreateRenderResult;\n }\n\n throw new Error(\n `Failed to create render ${response.status} ${response.statusText} ${await response.text()}`,\n );\n};\n\nexport const uploadRender = async (\n client: Client,\n renderId: string,\n fileStream: ReadableStream,\n) => {\n log(\"Uploading render\", renderId);\n const response = await client.authenticatedFetch(\n `/api/v1/renders/${renderId}/upload`,\n {\n method: \"POST\",\n body: fileStream,\n duplex: \"half\",\n },\n );\n\n if (response.ok) {\n return response.json();\n }\n\n throw new Error(\n `Failed to upload render ${response.status} ${response.statusText}`,\n );\n};\n\nexport const getRenderInfo = async (client: Client, id: string) => {\n const response = await client.authenticatedFetch(`/api/v1/renders/${id}`);\n return response.json() as Promise<LookupRenderByMd5Result>;\n};\n\nexport const lookupRenderByMd5 = async (\n client: Client,\n md5: string,\n): Promise<LookupRenderByMd5Result | null> => {\n const response = await client.authenticatedFetch(\n `/api/v1/renders/md5/${md5}`,\n {\n method: \"GET\",\n },\n );\n\n if (response.ok) {\n return (await response.json()) as LookupRenderByMd5Result;\n }\n\n if (response.status === 404) {\n return null;\n }\n\n throw new Error(\n `Failed to lookup render by md5 ${md5} ${response.status} ${response.statusText}`,\n );\n};\n\nexport const getRenderProgress = async (client: Client, id: string) => {\n const eventSource = await client.authenticatedEventSource(\n `/api/v1/renders/${id}/progress`,\n );\n\n return new CompletionIterator(eventSource);\n};\n\nexport const downloadRender = async (client: Client, id: string) => {\n const response = await client.authenticatedFetch(`/api/v1/renders/${id}.mp4`);\n\n if (response.ok) {\n return response;\n }\n\n throw new Error(\n `Failed to download render ${id} ${response.status} ${response.statusText}`,\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"renders.cjs","names":["z","output: RenderOutputConfiguration","assertTypesMatch","CompletionIterator"],"sources":["../../src/resources/renders.ts"],"sourcesContent":["import debug from \"debug\";\nimport { z } from \"zod\";\nimport type { Client } from \"../client.js\";\nimport { CompletionIterator } from \"../ProgressIterator.js\";\nimport { assertTypesMatch } from \"../utils/assertTypesMatch.ts\";\n\nconst log = debug(\"ef:api:renders\");\n\nconst H264Configuration = z.object({\n codec: z.literal(\"h264\"),\n});\n\nconst AACConfiguration = z.object({\n codec: z.literal(\"aac\"),\n});\n\nconst MP4Configuration = z.object({\n container: z.literal(\"mp4\"),\n video: H264Configuration,\n audio: AACConfiguration,\n});\n\nconst JpegConfiguration = z.object({\n container: z.literal(\"jpeg\"),\n quality: z.number().int().min(1).max(100).default(80).optional(),\n});\n\nconst PngConfiguration = z.object({\n container: z.literal(\"png\"),\n compression: z.number().int().min(1).max(100).default(80).optional(),\n transparency: z.boolean().default(false).optional(),\n});\n\nconst WebpConfiguration = z.object({\n container: z.literal(\"webp\"),\n quality: z.number().int().min(1).max(100).default(80).optional(),\n compression: z.number().int().min(0).max(6).default(4).optional(),\n transparency: z.boolean().default(false).optional(),\n});\n\nexport const RenderOutputConfiguration = z.discriminatedUnion(\"container\", [\n MP4Configuration,\n JpegConfiguration,\n PngConfiguration,\n WebpConfiguration,\n]);\n\nexport type RenderOutputConfiguration = z.infer<\n typeof RenderOutputConfiguration\n>;\n\nexport const CreateRenderPayload = z.object({\n md5: z.string().optional(),\n fps: z.number().int().min(1).max(120).default(30).optional(),\n width: z.number().int().min(2).optional(),\n height: z.number().int().min(2).optional(),\n work_slice_ms: z\n .number()\n .int()\n .min(1000)\n .max(10_000)\n .default(4_000)\n .optional(),\n html: z.string().optional(),\n metadata: z.record(z.string(), z.string()).optional(),\n duration_ms: z.number().int().optional(),\n strategy: z.enum([\"v1\"]).default(\"v1\").optional(),\n backend: z.enum([\"cpu\", \"gpu\"]).default(\"cpu\").optional(),\n output: RenderOutputConfiguration.default({\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n }).optional(),\n});\n\nexport const CreateRenderPayloadWithOutput = CreateRenderPayload.extend({\n output: RenderOutputConfiguration,\n});\n\nexport class OutputConfiguration {\n static parse(input?: any) {\n const output = RenderOutputConfiguration.parse(\n input ?? {\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n },\n );\n return new OutputConfiguration(output);\n }\n\n constructor(public readonly output: RenderOutputConfiguration) {}\n\n get isStill() {\n return (\n this.output.container === \"jpeg\" ||\n this.output.container === \"png\" ||\n this.output.container === \"webp\"\n );\n }\n\n get isVideo() {\n return this.output.container === \"mp4\";\n }\n\n get fileExtension() {\n return this.output.container;\n }\n\n get contentType() {\n if (this.isStill) {\n return `image/${this.fileExtension}`;\n }\n return `video/${this.fileExtension}`;\n }\n\n get container() {\n return this.output.container;\n }\n\n get jpegConfig() {\n return this.output.container === \"jpeg\" ? this.output : null;\n }\n\n get pngConfig() {\n return this.output.container === \"png\" ? this.output : null;\n }\n\n get webpConfig() {\n return this.output.container === \"webp\" ? this.output : null;\n }\n\n get mp4Config() {\n return this.output.container === \"mp4\" ? this.output : null;\n }\n}\n\nexport interface CreateRenderPayload {\n md5?: string;\n fps?: number;\n width?: number;\n height?: number;\n work_slice_ms?: number;\n html?: string;\n duration_ms?: number;\n metadata?: Record<string, string>;\n strategy?: \"v1\";\n backend?: \"cpu\" | \"gpu\";\n output?: z.infer<typeof RenderOutputConfiguration>;\n}\n\nassertTypesMatch<CreateRenderPayload, z.infer<typeof CreateRenderPayload>>(\n true,\n);\n\nexport interface CreateRenderResult {\n id: string;\n md5: string | null;\n status: \"complete\" | \"created\" | \"failed\" | \"pending\" | \"rendering\" | string;\n metadata: Record<string, string>;\n}\n\nexport interface LookupRenderByMd5Result {\n id: string;\n md5: string | null;\n status: \"complete\" | \"created\" | \"failed\" | \"pending\" | \"rendering\" | string;\n metadata: Record<string, string>;\n}\n\nexport const createRender = async (\n client: Client,\n payload: CreateRenderPayload,\n) => {\n log(\"Creating render\", payload);\n // FIXME: The order of optional/default matters in zod\n // And if we set the default last, the type is not inferred correctly\n // Manually applying defaults here is a hack\n payload.strategy ??= \"v1\";\n payload.work_slice_ms ??= 4_000;\n payload.output ??= {\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n };\n\n const response = await client.authenticatedFetch(\"/api/v1/renders\", {\n method: \"POST\",\n body: JSON.stringify(payload),\n });\n\n log(\"Render created\", response);\n if (response.ok) {\n return (await response.json()) as CreateRenderResult;\n }\n\n throw new Error(\n `Failed to create render ${response.status} ${response.statusText} ${await response.text()}`,\n );\n};\n\nexport const uploadRender = async (\n client: Client,\n renderId: string,\n fileStream: ReadableStream,\n) => {\n log(\"Uploading render\", renderId);\n const response = await client.authenticatedFetch(\n `/api/v1/renders/${renderId}/upload`,\n {\n method: \"POST\",\n body: fileStream,\n duplex: \"half\",\n },\n );\n\n if (response.ok) {\n return response.json();\n }\n\n throw new Error(\n `Failed to upload render ${response.status} ${response.statusText}`,\n );\n};\n\nexport const getRenderInfo = async (client: Client, id: string) => {\n const response = await client.authenticatedFetch(`/api/v1/renders/${id}`);\n return response.json() as Promise<LookupRenderByMd5Result>;\n};\n\nexport const lookupRenderByMd5 = async (\n client: Client,\n md5: string,\n): Promise<LookupRenderByMd5Result | null> => {\n const response = await client.authenticatedFetch(\n `/api/v1/renders/md5/${md5}`,\n {\n method: \"GET\",\n },\n );\n\n if (response.ok) {\n return (await response.json()) as LookupRenderByMd5Result;\n }\n\n if (response.status === 404) {\n return null;\n }\n\n throw new Error(\n `Failed to lookup render by md5 ${md5} ${response.status} ${response.statusText}`,\n );\n};\n\nexport const getRenderProgress = async (client: Client, id: string) => {\n const eventSource = await client.authenticatedEventSource(\n `/api/v1/renders/${id}/progress`,\n );\n\n return new CompletionIterator(eventSource);\n};\n\nexport const downloadRender = async (client: Client, id: string) => {\n const response = await client.authenticatedFetch(`/api/v1/renders/${id}.mp4`);\n\n if (response.ok) {\n return response;\n }\n\n throw new Error(\n `Failed to download render ${id} ${response.status} ${response.statusText}`,\n );\n};\n"],"mappings":"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"}
@@ -83,6 +83,7 @@ declare const CreateRenderPayload: z.ZodObject<{
83
83
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
84
84
  duration_ms: z.ZodOptional<z.ZodNumber>;
85
85
  strategy: z.ZodOptional<z.ZodDefault<z.ZodEnum<["v1"]>>>;
86
+ backend: z.ZodOptional<z.ZodDefault<z.ZodEnum<["cpu", "gpu"]>>>;
86
87
  output: z.ZodOptional<z.ZodDefault<z.ZodDiscriminatedUnion<"container", [z.ZodObject<{
87
88
  container: z.ZodLiteral<"mp4">;
88
89
  video: z.ZodObject<{
@@ -162,6 +163,7 @@ declare const CreateRenderPayload: z.ZodObject<{
162
163
  html?: string | undefined;
163
164
  metadata?: Record<string, string> | undefined;
164
165
  strategy?: "v1" | undefined;
166
+ backend?: "cpu" | "gpu" | undefined;
165
167
  output?: {
166
168
  video: {
167
169
  codec: "h264";
@@ -193,6 +195,7 @@ declare const CreateRenderPayload: z.ZodObject<{
193
195
  html?: string | undefined;
194
196
  metadata?: Record<string, string> | undefined;
195
197
  strategy?: "v1" | undefined;
198
+ backend?: "cpu" | "gpu" | undefined;
196
199
  output?: {
197
200
  video: {
198
201
  codec: "h264";
@@ -259,6 +262,7 @@ interface CreateRenderPayload {
259
262
  duration_ms?: number;
260
263
  metadata?: Record<string, string>;
261
264
  strategy?: "v1";
265
+ backend?: "cpu" | "gpu";
262
266
  output?: z.infer<typeof RenderOutputConfiguration>;
263
267
  }
264
268
  interface CreateRenderResult {
@@ -83,6 +83,7 @@ declare const CreateRenderPayload: z.ZodObject<{
83
83
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
84
84
  duration_ms: z.ZodOptional<z.ZodNumber>;
85
85
  strategy: z.ZodOptional<z.ZodDefault<z.ZodEnum<["v1"]>>>;
86
+ backend: z.ZodOptional<z.ZodDefault<z.ZodEnum<["cpu", "gpu"]>>>;
86
87
  output: z.ZodOptional<z.ZodDefault<z.ZodDiscriminatedUnion<"container", [z.ZodObject<{
87
88
  container: z.ZodLiteral<"mp4">;
88
89
  video: z.ZodObject<{
@@ -162,6 +163,7 @@ declare const CreateRenderPayload: z.ZodObject<{
162
163
  html?: string | undefined;
163
164
  metadata?: Record<string, string> | undefined;
164
165
  strategy?: "v1" | undefined;
166
+ backend?: "cpu" | "gpu" | undefined;
165
167
  output?: {
166
168
  video: {
167
169
  codec: "h264";
@@ -193,6 +195,7 @@ declare const CreateRenderPayload: z.ZodObject<{
193
195
  html?: string | undefined;
194
196
  metadata?: Record<string, string> | undefined;
195
197
  strategy?: "v1" | undefined;
198
+ backend?: "cpu" | "gpu" | undefined;
196
199
  output?: {
197
200
  video: {
198
201
  codec: "h264";
@@ -259,6 +262,7 @@ interface CreateRenderPayload {
259
262
  duration_ms?: number;
260
263
  metadata?: Record<string, string>;
261
264
  strategy?: "v1";
265
+ backend?: "cpu" | "gpu";
262
266
  output?: z.infer<typeof RenderOutputConfiguration>;
263
267
  }
264
268
  interface CreateRenderResult {
@@ -43,6 +43,7 @@ const CreateRenderPayload = z.object({
43
43
  metadata: z.record(z.string(), z.string()).optional(),
44
44
  duration_ms: z.number().int().optional(),
45
45
  strategy: z.enum(["v1"]).default("v1").optional(),
46
+ backend: z.enum(["cpu", "gpu"]).default("cpu").optional(),
46
47
  output: RenderOutputConfiguration.default({
47
48
  container: "mp4",
48
49
  video: { codec: "h264" },
@@ -1 +1 @@
1
- {"version":3,"file":"renders.js","names":["output: RenderOutputConfiguration"],"sources":["../../src/resources/renders.ts"],"sourcesContent":["import debug from \"debug\";\nimport { z } from \"zod\";\nimport type { Client } from \"../client.js\";\nimport { CompletionIterator } from \"../ProgressIterator.js\";\nimport { assertTypesMatch } from \"../utils/assertTypesMatch.ts\";\n\nconst log = debug(\"ef:api:renders\");\n\nconst H264Configuration = z.object({\n codec: z.literal(\"h264\"),\n});\n\nconst AACConfiguration = z.object({\n codec: z.literal(\"aac\"),\n});\n\nconst MP4Configuration = z.object({\n container: z.literal(\"mp4\"),\n video: H264Configuration,\n audio: AACConfiguration,\n});\n\nconst JpegConfiguration = z.object({\n container: z.literal(\"jpeg\"),\n quality: z.number().int().min(1).max(100).default(80).optional(),\n});\n\nconst PngConfiguration = z.object({\n container: z.literal(\"png\"),\n compression: z.number().int().min(1).max(100).default(80).optional(),\n transparency: z.boolean().default(false).optional(),\n});\n\nconst WebpConfiguration = z.object({\n container: z.literal(\"webp\"),\n quality: z.number().int().min(1).max(100).default(80).optional(),\n compression: z.number().int().min(0).max(6).default(4).optional(),\n transparency: z.boolean().default(false).optional(),\n});\n\nexport const RenderOutputConfiguration = z.discriminatedUnion(\"container\", [\n MP4Configuration,\n JpegConfiguration,\n PngConfiguration,\n WebpConfiguration,\n]);\n\nexport type RenderOutputConfiguration = z.infer<\n typeof RenderOutputConfiguration\n>;\n\nexport const CreateRenderPayload = z.object({\n md5: z.string().optional(),\n fps: z.number().int().min(1).max(120).default(30).optional(),\n width: z.number().int().min(2).optional(),\n height: z.number().int().min(2).optional(),\n work_slice_ms: z\n .number()\n .int()\n .min(1000)\n .max(10_000)\n .default(4_000)\n .optional(),\n html: z.string().optional(),\n metadata: z.record(z.string(), z.string()).optional(),\n duration_ms: z.number().int().optional(),\n strategy: z.enum([\"v1\"]).default(\"v1\").optional(),\n output: RenderOutputConfiguration.default({\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n }).optional(),\n});\n\nexport const CreateRenderPayloadWithOutput = CreateRenderPayload.extend({\n output: RenderOutputConfiguration,\n});\n\nexport class OutputConfiguration {\n static parse(input?: any) {\n const output = RenderOutputConfiguration.parse(\n input ?? {\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n },\n );\n return new OutputConfiguration(output);\n }\n\n constructor(public readonly output: RenderOutputConfiguration) {}\n\n get isStill() {\n return (\n this.output.container === \"jpeg\" ||\n this.output.container === \"png\" ||\n this.output.container === \"webp\"\n );\n }\n\n get isVideo() {\n return this.output.container === \"mp4\";\n }\n\n get fileExtension() {\n return this.output.container;\n }\n\n get contentType() {\n if (this.isStill) {\n return `image/${this.fileExtension}`;\n }\n return `video/${this.fileExtension}`;\n }\n\n get container() {\n return this.output.container;\n }\n\n get jpegConfig() {\n return this.output.container === \"jpeg\" ? this.output : null;\n }\n\n get pngConfig() {\n return this.output.container === \"png\" ? this.output : null;\n }\n\n get webpConfig() {\n return this.output.container === \"webp\" ? this.output : null;\n }\n\n get mp4Config() {\n return this.output.container === \"mp4\" ? this.output : null;\n }\n}\n\nexport interface CreateRenderPayload {\n md5?: string;\n fps?: number;\n width?: number;\n height?: number;\n work_slice_ms?: number;\n html?: string;\n duration_ms?: number;\n metadata?: Record<string, string>;\n strategy?: \"v1\";\n output?: z.infer<typeof RenderOutputConfiguration>;\n}\n\nassertTypesMatch<CreateRenderPayload, z.infer<typeof CreateRenderPayload>>(\n true,\n);\n\nexport interface CreateRenderResult {\n id: string;\n md5: string | null;\n status: \"complete\" | \"created\" | \"failed\" | \"pending\" | \"rendering\" | string;\n metadata: Record<string, string>;\n}\n\nexport interface LookupRenderByMd5Result {\n id: string;\n md5: string | null;\n status: \"complete\" | \"created\" | \"failed\" | \"pending\" | \"rendering\" | string;\n metadata: Record<string, string>;\n}\n\nexport const createRender = async (\n client: Client,\n payload: CreateRenderPayload,\n) => {\n log(\"Creating render\", payload);\n // FIXME: The order of optional/default matters in zod\n // And if we set the default last, the type is not inferred correctly\n // Manually applying defaults here is a hack\n payload.strategy ??= \"v1\";\n payload.work_slice_ms ??= 4_000;\n payload.output ??= {\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n };\n\n const response = await client.authenticatedFetch(\"/api/v1/renders\", {\n method: \"POST\",\n body: JSON.stringify(payload),\n });\n\n log(\"Render created\", response);\n if (response.ok) {\n return (await response.json()) as CreateRenderResult;\n }\n\n throw new Error(\n `Failed to create render ${response.status} ${response.statusText} ${await response.text()}`,\n );\n};\n\nexport const uploadRender = async (\n client: Client,\n renderId: string,\n fileStream: ReadableStream,\n) => {\n log(\"Uploading render\", renderId);\n const response = await client.authenticatedFetch(\n `/api/v1/renders/${renderId}/upload`,\n {\n method: \"POST\",\n body: fileStream,\n duplex: \"half\",\n },\n );\n\n if (response.ok) {\n return response.json();\n }\n\n throw new Error(\n `Failed to upload render ${response.status} ${response.statusText}`,\n );\n};\n\nexport const getRenderInfo = async (client: Client, id: string) => {\n const response = await client.authenticatedFetch(`/api/v1/renders/${id}`);\n return response.json() as Promise<LookupRenderByMd5Result>;\n};\n\nexport const lookupRenderByMd5 = async (\n client: Client,\n md5: string,\n): Promise<LookupRenderByMd5Result | null> => {\n const response = await client.authenticatedFetch(\n `/api/v1/renders/md5/${md5}`,\n {\n method: \"GET\",\n },\n );\n\n if (response.ok) {\n return (await response.json()) as LookupRenderByMd5Result;\n }\n\n if (response.status === 404) {\n return null;\n }\n\n throw new Error(\n `Failed to lookup render by md5 ${md5} ${response.status} ${response.statusText}`,\n );\n};\n\nexport const getRenderProgress = async (client: Client, id: string) => {\n const eventSource = await client.authenticatedEventSource(\n `/api/v1/renders/${id}/progress`,\n );\n\n return new CompletionIterator(eventSource);\n};\n\nexport const downloadRender = async (client: Client, id: string) => {\n const response = await client.authenticatedFetch(`/api/v1/renders/${id}.mp4`);\n\n if (response.ok) {\n return response;\n }\n\n throw new Error(\n `Failed to download render ${id} ${response.status} ${response.statusText}`,\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"renders.js","names":["output: RenderOutputConfiguration"],"sources":["../../src/resources/renders.ts"],"sourcesContent":["import debug from \"debug\";\nimport { z } from \"zod\";\nimport type { Client } from \"../client.js\";\nimport { CompletionIterator } from \"../ProgressIterator.js\";\nimport { assertTypesMatch } from \"../utils/assertTypesMatch.ts\";\n\nconst log = debug(\"ef:api:renders\");\n\nconst H264Configuration = z.object({\n codec: z.literal(\"h264\"),\n});\n\nconst AACConfiguration = z.object({\n codec: z.literal(\"aac\"),\n});\n\nconst MP4Configuration = z.object({\n container: z.literal(\"mp4\"),\n video: H264Configuration,\n audio: AACConfiguration,\n});\n\nconst JpegConfiguration = z.object({\n container: z.literal(\"jpeg\"),\n quality: z.number().int().min(1).max(100).default(80).optional(),\n});\n\nconst PngConfiguration = z.object({\n container: z.literal(\"png\"),\n compression: z.number().int().min(1).max(100).default(80).optional(),\n transparency: z.boolean().default(false).optional(),\n});\n\nconst WebpConfiguration = z.object({\n container: z.literal(\"webp\"),\n quality: z.number().int().min(1).max(100).default(80).optional(),\n compression: z.number().int().min(0).max(6).default(4).optional(),\n transparency: z.boolean().default(false).optional(),\n});\n\nexport const RenderOutputConfiguration = z.discriminatedUnion(\"container\", [\n MP4Configuration,\n JpegConfiguration,\n PngConfiguration,\n WebpConfiguration,\n]);\n\nexport type RenderOutputConfiguration = z.infer<\n typeof RenderOutputConfiguration\n>;\n\nexport const CreateRenderPayload = z.object({\n md5: z.string().optional(),\n fps: z.number().int().min(1).max(120).default(30).optional(),\n width: z.number().int().min(2).optional(),\n height: z.number().int().min(2).optional(),\n work_slice_ms: z\n .number()\n .int()\n .min(1000)\n .max(10_000)\n .default(4_000)\n .optional(),\n html: z.string().optional(),\n metadata: z.record(z.string(), z.string()).optional(),\n duration_ms: z.number().int().optional(),\n strategy: z.enum([\"v1\"]).default(\"v1\").optional(),\n backend: z.enum([\"cpu\", \"gpu\"]).default(\"cpu\").optional(),\n output: RenderOutputConfiguration.default({\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n }).optional(),\n});\n\nexport const CreateRenderPayloadWithOutput = CreateRenderPayload.extend({\n output: RenderOutputConfiguration,\n});\n\nexport class OutputConfiguration {\n static parse(input?: any) {\n const output = RenderOutputConfiguration.parse(\n input ?? {\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n },\n );\n return new OutputConfiguration(output);\n }\n\n constructor(public readonly output: RenderOutputConfiguration) {}\n\n get isStill() {\n return (\n this.output.container === \"jpeg\" ||\n this.output.container === \"png\" ||\n this.output.container === \"webp\"\n );\n }\n\n get isVideo() {\n return this.output.container === \"mp4\";\n }\n\n get fileExtension() {\n return this.output.container;\n }\n\n get contentType() {\n if (this.isStill) {\n return `image/${this.fileExtension}`;\n }\n return `video/${this.fileExtension}`;\n }\n\n get container() {\n return this.output.container;\n }\n\n get jpegConfig() {\n return this.output.container === \"jpeg\" ? this.output : null;\n }\n\n get pngConfig() {\n return this.output.container === \"png\" ? this.output : null;\n }\n\n get webpConfig() {\n return this.output.container === \"webp\" ? this.output : null;\n }\n\n get mp4Config() {\n return this.output.container === \"mp4\" ? this.output : null;\n }\n}\n\nexport interface CreateRenderPayload {\n md5?: string;\n fps?: number;\n width?: number;\n height?: number;\n work_slice_ms?: number;\n html?: string;\n duration_ms?: number;\n metadata?: Record<string, string>;\n strategy?: \"v1\";\n backend?: \"cpu\" | \"gpu\";\n output?: z.infer<typeof RenderOutputConfiguration>;\n}\n\nassertTypesMatch<CreateRenderPayload, z.infer<typeof CreateRenderPayload>>(\n true,\n);\n\nexport interface CreateRenderResult {\n id: string;\n md5: string | null;\n status: \"complete\" | \"created\" | \"failed\" | \"pending\" | \"rendering\" | string;\n metadata: Record<string, string>;\n}\n\nexport interface LookupRenderByMd5Result {\n id: string;\n md5: string | null;\n status: \"complete\" | \"created\" | \"failed\" | \"pending\" | \"rendering\" | string;\n metadata: Record<string, string>;\n}\n\nexport const createRender = async (\n client: Client,\n payload: CreateRenderPayload,\n) => {\n log(\"Creating render\", payload);\n // FIXME: The order of optional/default matters in zod\n // And if we set the default last, the type is not inferred correctly\n // Manually applying defaults here is a hack\n payload.strategy ??= \"v1\";\n payload.work_slice_ms ??= 4_000;\n payload.output ??= {\n container: \"mp4\",\n video: {\n codec: \"h264\",\n },\n audio: {\n codec: \"aac\",\n },\n };\n\n const response = await client.authenticatedFetch(\"/api/v1/renders\", {\n method: \"POST\",\n body: JSON.stringify(payload),\n });\n\n log(\"Render created\", response);\n if (response.ok) {\n return (await response.json()) as CreateRenderResult;\n }\n\n throw new Error(\n `Failed to create render ${response.status} ${response.statusText} ${await response.text()}`,\n );\n};\n\nexport const uploadRender = async (\n client: Client,\n renderId: string,\n fileStream: ReadableStream,\n) => {\n log(\"Uploading render\", renderId);\n const response = await client.authenticatedFetch(\n `/api/v1/renders/${renderId}/upload`,\n {\n method: \"POST\",\n body: fileStream,\n duplex: \"half\",\n },\n );\n\n if (response.ok) {\n return response.json();\n }\n\n throw new Error(\n `Failed to upload render ${response.status} ${response.statusText}`,\n );\n};\n\nexport const getRenderInfo = async (client: Client, id: string) => {\n const response = await client.authenticatedFetch(`/api/v1/renders/${id}`);\n return response.json() as Promise<LookupRenderByMd5Result>;\n};\n\nexport const lookupRenderByMd5 = async (\n client: Client,\n md5: string,\n): Promise<LookupRenderByMd5Result | null> => {\n const response = await client.authenticatedFetch(\n `/api/v1/renders/md5/${md5}`,\n {\n method: \"GET\",\n },\n );\n\n if (response.ok) {\n return (await response.json()) as LookupRenderByMd5Result;\n }\n\n if (response.status === 404) {\n return null;\n }\n\n throw new Error(\n `Failed to lookup render by md5 ${md5} ${response.status} ${response.statusText}`,\n );\n};\n\nexport const getRenderProgress = async (client: Client, id: string) => {\n const eventSource = await client.authenticatedEventSource(\n `/api/v1/renders/${id}/progress`,\n );\n\n return new CompletionIterator(eventSource);\n};\n\nexport const downloadRender = async (client: Client, id: string) => {\n const response = await client.authenticatedFetch(`/api/v1/renders/${id}.mp4`);\n\n if (response.ok) {\n return response;\n }\n\n throw new Error(\n `Failed to download render ${id} ${response.status} ${response.statusText}`,\n );\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/api",
3
- "version": "0.40.1-beta.0",
3
+ "version": "0.40.3",
4
4
  "description": "API functions for EditFrame",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,7 +24,7 @@
24
24
  "typescript": "^5.9.3"
25
25
  },
26
26
  "dependencies": {
27
- "@editframe/assets": "0.40.0",
27
+ "@editframe/assets": "0.40.3",
28
28
  "@vitejs/plugin-react": "^4.3.4",
29
29
  "debug": "^4.3.5",
30
30
  "eventsource-parser": "^3.0.0",
@@ -108,4 +108,4 @@
108
108
  "./types.json": "./types.json"
109
109
  }
110
110
  }
111
- }
111
+ }