Missing API
Uploader offers no public way to intervene between "user dropped/selected files" and "the uploader starts writing into the target entity".
Uploader accepts no upload-event props — UploaderProps is only { entity, fileType, children } (src/components/Uploader.tsx:16), and the events passed to useFillEntity are hardcoded noops (src/components/Uploader.tsx:72).
useFillEntity closes over the entity accessor captured at mount when disconnecting/filling (src/internal/hooks/useFillEntity.ts:54), so the target cannot be swapped for an upload already in flight.
Use case (copy-on-write)
In a CMS media-library setup, a block references a shared ImageAsset (manyHasOne) whose image is the uploader target (<Uploader entity={block.imageAsset.image}>). When the referenced asset is already persisted (shared with other blocks), uploading a replacement file must NOT mutate the shared row in place — the block should first fork to a fresh asset and the upload should land there. Without a pre-upload hook there is no supported way to do this.
Current workaround (downstream)
We override UploaderUploadFilesContext between Uploader and UploaderDropzoneRoot: the wrapped dispatch queues the dropped File[], forks the relation ($disconnect() + $create(...)), remounts the Uploader via key={asset.$entity.id}, and an effect replays the queued files through the fresh uploader's raw useUploaderUploadFiles(). It works because UploaderDropzoneRoot takes its onDrop from that context (src/components/UploaderDropzoneRoot.tsx:13), but it leans on remount timing and on the context being a stable public seam.
Suggested API
Either of:
- an async-capable
onBeforeUpload(files: File[]) => File[] | false | Promise<...> prop on Uploader that runs before the entity write and after which the entity path is re-resolved, or
- lazy per-upload resolution of the
entity accessor (resolve the path at dispatch time instead of capturing at mount), which would make fork-then-upload work without remounting.
Missing API
Uploaderoffers no public way to intervene between "user dropped/selected files" and "the uploader starts writing into the target entity".Uploaderaccepts no upload-event props —UploaderPropsis only{ entity, fileType, children }(src/components/Uploader.tsx:16), and the events passed touseFillEntityare hardcoded noops (src/components/Uploader.tsx:72).useFillEntitycloses over theentityaccessor captured at mount when disconnecting/filling (src/internal/hooks/useFillEntity.ts:54), so the target cannot be swapped for an upload already in flight.Use case (copy-on-write)
In a CMS media-library setup, a block references a shared
ImageAsset(manyHasOne) whoseimageis the uploader target (<Uploader entity={block.imageAsset.image}>). When the referenced asset is already persisted (shared with other blocks), uploading a replacement file must NOT mutate the shared row in place — the block should first fork to a fresh asset and the upload should land there. Without a pre-upload hook there is no supported way to do this.Current workaround (downstream)
We override
UploaderUploadFilesContextbetweenUploaderandUploaderDropzoneRoot: the wrapped dispatch queues the droppedFile[], forks the relation ($disconnect()+$create(...)), remounts theUploaderviakey={asset.$entity.id}, and an effect replays the queued files through the fresh uploader's rawuseUploaderUploadFiles(). It works becauseUploaderDropzoneRoottakes itsonDropfrom that context (src/components/UploaderDropzoneRoot.tsx:13), but it leans on remount timing and on the context being a stable public seam.Suggested API
Either of:
onBeforeUpload(files: File[]) => File[] | false | Promise<...>prop onUploaderthat runs before the entity write and after which theentitypath is re-resolved, orentityaccessor (resolve the path at dispatch time instead of capturing at mount), which would make fork-then-upload work without remounting.