routier-collection / plugins/blob/src / FileUploader
Type Alias: FileUploader
FileUploader =
Pick<Files,"upload">
Defined in: plugins/blob/src/BlobDbPlugin.ts:47
Turns file content into a file reference on the way to your real plugin.
s.file() accepts content and stores a reference. This is what performs that swap, and it is the only place it can happen: the generated preprocess is synchronous and is called from the change tracker and the broadcast path, so it cannot await an upload. bulkPersist can.
class AppStore extends DataStore {
documents = this.collection(documentSchema).proxy().create();
constructor() {
super(new BlobDbPlugin(new DexiePlugin('app'), files));
}
}
await store.documents.addAsync({ title: 'Q3', file: fileFromInput });
await store.saveChangesAsync(); // uploads, then writes the rowUploads happen before the rows, and are not part of their transaction
They cannot be. A blob store has no transaction to enlist in, so "both or neither" is not available at any price. What this does instead is order the failure: content is uploaded first, and only then are the rows handed to the inner plugin inside its own transaction. A save that fails after an upload leaves an orphan, which costs storage and breaks nothing and sweepOrphans collects. The other order would leave a row pointing at bytes that were never written.
Uploads are idempotent because keys are content-addressed, so a retried save re-uploads nothing.