IMAGES-1177: Implement wrapped Images binding#2188
IMAGES-1177: Implement wrapped Images binding#2188irvinebroque merged 1 commit intocloudflare:mainfrom
Conversation
06058b5 to
bde005a
Compare
|
lgtm |
IgorMinar
left a comment
There was a problem hiding this comment.
I'm excited about this addition! I have some API design feedback, please take a look...
| } | ||
|
|
||
| interface TransformationResult { | ||
| response(): Response; |
There was a problem hiding this comment.
Could you avoid making the result of type Response as that leaks the underlying transport layer. You already expose image as a readable stream which is perfect. Do we need to expose more?
There was a problem hiding this comment.
This is just a convenience that does:
new Response(this.image(), {
headers: {
"content-type": this.contentType(),
},
});so I don't think it leaks anything, but happy to remove it if you don't think it's useful
types/defines/images.d.ts
Outdated
| } | ||
|
|
||
| interface ImagesError { | ||
| code: number; |
There was a problem hiding this comment.
I wonder if there is a precedence for error handling in bindings. It seems that R2 and D1 as preexisting APIs take vastly different approach to this.
Could we think about which way we want to go in this area, and start consolidating the error APIs to feel consistent?
There was a problem hiding this comment.
at minimum this property should be readonly. For reference this is what R2Error looks like:
declare interface R2Error extends Error {
readonly name: string;
readonly code: number;
readonly message: string;
readonly action: string;
readonly stack: any;
}
source: https://unpkg.com/browse/@cloudflare/workers-types@4.20240614.0/experimental/index.d.ts
There was a problem hiding this comment.
Made it this for now:
interface ImagesError extends Error {
readonly code: number;
readonly message: string;
readonly stack?: string;
}It's fairly similar to the Vectorize error (which I cribbed from shamelessly)
types/defines/images.d.ts
Outdated
|
|
||
| interface ImagesBinding { | ||
| info(blob: Blob): Promise<InfoResponse>; | ||
| input(blob: Blob): ImageTransformer; |
There was a problem hiding this comment.
could the input be a stream instead? It's easy to turn a blob to a stream, the opposite is problematic.
There was a problem hiding this comment.
my main goal here is to enable streaming transformations/use-cases by default, because enabling that ad-hoc will be hard/awkward.
There was a problem hiding this comment.
I've made the interfaces take streams and then buffer internally for now as it's a bit tricky to stream properly with multipart, which is what the backend uses
|
one more thing... this feature is really cool, but it will not be very useful if we don't come up with a local development story for it. Have you thought about how can one develop a worker locally with wrangler and miniflare and still use this new binding? |
bde005a to
acca5dd
Compare
|
Thanks for the review!
I think the approach taken with the AI binding will work nicely here: provide an endpoint on api.cloudflare.com with OAuth that proxies to a worker that invokes the binding. |
|
Like Igor, very excited for this! I've personally needed it many many times :) |
| const chunks: Uint8Array[] = []; | ||
| const reader = stream.getReader(); | ||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
|
|
||
| if (value) { | ||
| chunks.push(value); | ||
| } | ||
|
|
||
| if (done) { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return new Blob(chunks); |
There was a problem hiding this comment.
Worth measuring but in theory it would be more efficient to avoid bouncing back and forth between C++ and JS:
| const chunks: Uint8Array[] = []; | |
| const reader = stream.getReader(); | |
| while (true) { | |
| const { done, value } = await reader.read(); | |
| if (value) { | |
| chunks.push(value); | |
| } | |
| if (done) { | |
| break; | |
| } | |
| } | |
| return new Blob(chunks); | |
| return new Response(stream).blob(); |
There was a problem hiding this comment.
Made this change, also much more obviously correct which is a plus for me!
acca5dd to
c84d67c
Compare
c84d67c to
5d24095
Compare
This creates a new TS binding that allows image transformations and makes it available as an internal Cloudflare binding.
5d24095 to
e7b29af
Compare
This creates a new TS binding that allows image transformations and makes it available as an internal Cloudflare binding.