{"version":3,"file":"index.mjs","sources":["../../src/converters.ts","../../src/vue/composable.ts","../../src/vue/ObjectToFile.vue","../../src/vue/index.ts"],"sourcesContent":["import type { GraffitiFileObject, GraffitiFilePutObject } from \"./schemas\";\n\n/**\n * Converts a [File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n * to a [Graffiti object](https://api.graffiti.garden/interfaces/GraffitiObjectBase.html)\n * that can be [put](https://api.graffiti.garden/classes/Graffiti.html#put)\n * like a normal Graffiti object.\n */\nexport async function fileToGraffitiObject(\n  /**\n   * The [File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n   * to be converted to a Graffiti object. It must be less than 4MB in size.\n   *\n   * This can be a file from an [HTML file input](https://developer.mozilla.org/en-US/docs/Web/API/File).\n   */\n  file: File,\n) {\n  // Reject if the file is bigger than 4MB\n  if (file.size > 4 * 1024 * 1024) {\n    throw new Error(\"File is too large. Please make sure it is less than 4MB.\");\n  }\n\n  return new Promise<GraffitiFilePutObject>((resolve, reject) => {\n    const reader = new FileReader();\n    reader.readAsDataURL(file);\n    reader.onload = () => {\n      if (typeof reader.result !== \"string\") {\n        reject(new Error(\"Expected a string\"));\n      } else {\n        resolve({\n          value: {\n            data: reader.result,\n            name: file.name,\n            mimetype: file.type,\n          },\n          channels: [],\n        });\n      }\n    };\n    reader.onerror = (error) => reject(error);\n  });\n}\n\n/**\n * Converts a [Graffiti object](https://api.graffiti.garden/interfaces/GraffitiObjectBase.html)\n * containing a [File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n * encoded by {@link fileToGraffitiObject} back to a File.\n */\nexport async function graffitiObjectToFile(object: GraffitiFileObject) {\n  const base64 = object.value;\n  const response = await fetch(base64.data);\n  const blob = await response.blob();\n  const file = new File([blob], base64.name, { type: base64.mimetype });\n  const fileDataUrl = URL.createObjectURL(file);\n  return {\n    /**\n     * The [File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n     * extracted from the Graffiti object.\n     */\n    file,\n    /**\n     * The file as a [data URL](https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data)\n     * which can be used as a `src` for an `<img>` tag or other media elements.\n     */\n    fileDataUrl,\n  };\n}\n","import { ref, type Ref, watch, type MaybeRefOrGetter, toValue } from \"vue\";\nimport { graffitiObjectToFile } from \"../converters\";\nimport type { GraffitiFileObject } from \"../schemas\";\n\n/**\n * A Vue.js [composable](https://vuejs.org/guide/reusability/composables.html)\n * that asynchronously converts a reactive Graffiti object\n * into a [File](https://developer.mozilla.org/en-US/docs/Web/API/File).\n *\n * If the object is loading (`undefined`), or not found (`null`),\n * the `file` and `fileDataUrl` properties will be `undefined` or `null`.\n */\nexport function useGraffitiObjectToFile(\n  object: MaybeRefOrGetter<GraffitiFileObject | undefined | null>,\n) {\n  const file: Ref<File | undefined | null> = ref();\n  const fileDataUrl: Ref<string | undefined | null> = ref();\n  watch(\n    () => toValue(object),\n    async (object) => {\n      const outputs = object ? await graffitiObjectToFile(object) : object;\n      file.value = outputs ? outputs.file : outputs;\n      fileDataUrl.value = outputs ? outputs.fileDataUrl : outputs;\n    },\n    {\n      immediate: true,\n    },\n  );\n\n  return {\n    /**\n     * The [File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n     * extracted from the Graffiti object.\n     */\n    file,\n    /**\n     * The file data as a [data URL](https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data)\n     * which can be used as a `src` for an `<img>` tag or other media elements.\n     */\n    fileDataUrl,\n  };\n}\n","<script setup lang=\"ts\">\nimport { useGraffitiObjectToFile } from \"./composable\";\nimport type { GraffitiFileObject } from \"../schemas\";\n\nconst props = defineProps<{\n    object: GraffitiFileObject | null | undefined;\n}>();\n\nconst slots = defineSlots<{\n    default?(props: {\n        file: File | undefined | null;\n        fileDataUrl: string | undefined | null;\n    }): any;\n}>();\n\nconst { file, fileDataUrl } = useGraffitiObjectToFile(() => props.object);\n</script>\n\n<template>\n    <slot :file=\"file\" :fileDataUrl=\"fileDataUrl\"></slot>\n</template>\n","export { useGraffitiObjectToFile } from \"./composable\";\nimport ObjectToFile from \"./ObjectToFile.vue\";\nexport const GraffitiObjectToFile = ObjectToFile;\n"],"names":["graffitiObjectToFile","object","base64","blob","file","fileDataUrl","useGraffitiObjectToFile","ref","watch","toValue","outputs","props","__props","_useSlots","GraffitiObjectToFile","ObjectToFile"],"mappings":";AAgDA,eAAsBA,EAAqBC,GAA4B;AACrE,QAAMC,IAASD,EAAO,OAEhBE,IAAO,OADI,MAAM,MAAMD,EAAO,IAAI,GACZ,KAAK,GAC3BE,IAAO,IAAI,KAAK,CAACD,CAAI,GAAGD,EAAO,MAAM,EAAE,MAAMA,EAAO,SAAA,CAAU,GAC9DG,IAAc,IAAI,gBAAgBD,CAAI;AACrC,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKL,MAAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,aAAAC;AAAA,EACF;AACF;ACtDO,SAASC,EACdL,GACA;AACA,QAAMG,IAAqCG,EAAI,GACzCF,IAA8CE,EAAI;AACxD,SAAAC;AAAA,IACE,MAAMC,EAAQR,CAAM;AAAA,IACpB,OAAOA,MAAW;AAChB,YAAMS,IAAUT,KAAS,MAAMD,EAAqBC,CAAM;AACrD,MAAAG,EAAA,QAAQM,KAAUA,EAAQ,MACnBL,EAAA,QAAQK,KAAUA,EAAQ;AAAA,IACxC;AAAA,IACA;AAAA,MACE,WAAW;AAAA,IAAA;AAAA,EAEf,GAEO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKL,MAAAN;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,aAAAC;AAAA,EACF;AACF;;;;;;;ACrCA,UAAMM,IAAQC;AAIAC,IAAAA,EAKV;AAEJ,UAAM,EAAE,MAAAT,GAAM,aAAAC,EAAA,IAAgBC,EAAwB,MAAMK,EAAM,MAAM;;;;;;ICb3DG,IAAuBC;"}