Upload file XState machine with Effect

XState machine to extract a File from an html input with type="file".

The machine has an "upload-file" event that accept event from onChange on input. Inside an actor the HtmlChangeEvent effect service extract the first File.

The File is then stored inside the machine context. In case of error we store a submitError.

The machine can be extended by adding logic inside the actor (for example uploading the File somewhere).

Languages

typescript

Libraries

xstateeffect
import { Context, Data, Effect, Layer } from "effect";

class MissingFileError extends Data.TaggedError("MissingFileError")<{}> {}

const make = (event: React.ChangeEvent<HTMLInputElement>) => ({
  getRequiredFile: Effect.fromNullable(event.target.files?.item(0)).pipe(
    Effect.mapError(() => new MissingFileError())
  ),
});

export class HtmlChangeEvent extends Context.Tag("HtmlChangeEvent")<
  HtmlChangeEvent,
  Readonly<ReturnType<typeof make>>
>() {
  static readonly fromEvent = (event: React.ChangeEvent<HTMLInputElement>) =>
    Layer.succeed(this, make(event));
}