{"version":3,"file":"useJobStatusChannel-DfULOaTP.js","sources":["../../../packs/frontend/composables/useJobStatusChannel.ts"],"sourcesContent":["import { useActionCableChannel } from \"@/composables/useActionCableChannel\";\nimport {\n ActionCableSubscription,\n ActionCableData,\n ActionCableJobStatusData,\n} from \"@/types\";\nimport { flash } from \"@/utils/flash\";\n\nlet actionCableSubscription: ActionCableSubscription | undefined;\ntype OnUpdateCallback = {\n onUpdate: (data: ActionCableJobStatusData, payload: unknown) => void;\n};\nconst onUpdateListeners: OnUpdateCallback[\"onUpdate\"][] = [];\n\n// Subscribe to the CurrentUserJobStatusChannel channel and call the onUpdate\nexport function useJobStatusChannel({ onUpdate }: OnUpdateCallback) {\n const { t } = useI18n();\n const userStore = useUserStore();\n\n onUpdateListeners.push(onUpdate);\n\n // onUpdate callback for the CurrentUserJobStatusChannel has a different data type\n // with additional properties compared to the default ActionCableData\n const onUpdateCallback = (data: ActionCableData) => {\n const jobStatusData = data as ActionCableJobStatusData;\n\n // typically an ActiveRecord object\n const payload = (data.payload && JSON.parse(data.payload)) || {};\n\n if (jobStatusData.status === \"failed\") {\n flash(FlashKindEnum.ALERT, resolveErrorMessage(jobStatusData));\n }\n\n onUpdateListeners.forEach((listener) => {\n listener(jobStatusData, payload);\n });\n };\n\n const handleSubscriptionChange = () => {\n if (userStore.isAuthenticated || userStore.isVisitor) {\n setupSubscription();\n } else {\n if (actionCableSubscription) {\n actionCableSubscription.unsubscribe();\n }\n }\n };\n\n watch(\n () => userStore.isAuthenticated,\n () => {\n handleSubscriptionChange();\n }\n );\n\n watch(\n () => userStore.isVisitor,\n () => {\n handleSubscriptionChange();\n }\n );\n\n onMounted(() => {\n if (userStore.isAuthenticated || userStore.isVisitor) {\n setupSubscription();\n }\n });\n\n onUnmounted(() => {\n // remove onUpdate callback\n if (onUpdate) {\n onUpdateListeners.splice(onUpdateListeners.indexOf(onUpdate), 1);\n }\n\n // if no more onUpdate callbacks, unsubscribe from the channel\n if (actionCableSubscription && onUpdateListeners.length === 0) {\n actionCableSubscription.unsubscribe();\n actionCableSubscription = undefined;\n }\n });\n\n const setupSubscription = () => {\n if (!actionCableSubscription) {\n actionCableSubscription = useActionCableChannel(\n \"CurrentUserJobStatusChannel\",\n {},\n {\n onUpdate: onUpdateCallback,\n }\n );\n }\n };\n\n const GENERIC_EXCEPTIONS = [\n \"ActiveRecord::RecordInvalid\",\n \"ArgumentError\",\n \"RuntimeError\",\n ];\n\n const resolveErrorMessage = (\n jobStatusData: ActionCableJobStatusData\n ): string => {\n // map ruby exceptions to i18n strings\n // example: OpenAi::TimeoutError -> \"Our partner OpenAI is currently experiencing too many requests. Please try again later.\"\n const errorMessage = t(\n `exceptionMessages.${jobStatusData?.exception || \"default\"}`,\n {\n message: jobStatusData?.message,\n }\n );\n\n if (\n jobStatusData?.exception &&\n GENERIC_EXCEPTIONS.includes(jobStatusData?.exception)\n ) {\n return t(\"errors.jobProcessingFailedWithDetails\", {\n message: jobStatusData.message,\n });\n } else if (errorMessage && errorMessage.length > 0) {\n return errorMessage;\n } else {\n return jobStatusData.message || t(\"errors.jobProcessingFailed\");\n }\n };\n\n return { actionCableSubscription };\n}\n"],"names":["actionCableSubscription","onUpdateListeners","useJobStatusChannel","onUpdate","useI18n","userStore","useUserStore","onUpdateCallback","data","jobStatusData","payload","flash","FlashKindEnum","resolveErrorMessage","listener","handleSubscriptionChange","setupSubscription","watch","onMounted","onUnmounted","useActionCableChannel","GENERIC_EXCEPTIONS","errorMessage"],"mappings":"iJAQA,IAAIA,EAIJ,MAAMC,EAAoD,CAAC,EAG3C,SAAAC,EAAoB,CAAE,SAAAC,GAA8B,CAC5D,KAAA,CAAE,CAAE,EAAIC,EAAQ,EAChBC,EAAYC,EAAa,EAE/BL,EAAkB,KAAKE,CAAQ,EAIzB,MAAAI,EAAoBC,GAA0B,CAClD,MAAMC,EAAgBD,EAGhBE,EAAWF,EAAK,SAAW,KAAK,MAAMA,EAAK,OAAO,GAAM,CAAC,EAE3DC,EAAc,SAAW,UAC3BE,EAAMC,EAAc,MAAOC,EAAoBJ,CAAa,CAAC,EAG7CR,EAAA,QAASa,GAAa,CACtCA,EAASL,EAAeC,CAAO,CAAA,CAChC,CACH,EAEMK,EAA2B,IAAM,CACjCV,EAAU,iBAAmBA,EAAU,UACvBW,EAAA,EAEdhB,GACFA,EAAwB,YAAY,CAG1C,EAEAiB,EACE,IAAMZ,EAAU,gBAChB,IAAM,CACqBU,EAAA,CAAA,CAE7B,EAEAE,EACE,IAAMZ,EAAU,UAChB,IAAM,CACqBU,EAAA,CAAA,CAE7B,EAEAG,EAAU,IAAM,EACVb,EAAU,iBAAmBA,EAAU,YACvBW,EAAA,CACpB,CACD,EAEDG,EAAY,IAAM,CAEZhB,GACFF,EAAkB,OAAOA,EAAkB,QAAQE,CAAQ,EAAG,CAAC,EAI7DH,GAA2BC,EAAkB,SAAW,IAC1DD,EAAwB,YAAY,EACVA,EAAA,OAC5B,CACD,EAED,MAAMgB,EAAoB,IAAM,CACzBhB,IACuBA,EAAAoB,EACxB,8BACA,CAAC,EACD,CACE,SAAUb,CAAA,CAEd,EAEJ,EAEMc,EAAqB,CACzB,8BACA,gBACA,cACF,EAEMR,EACJJ,GACW,CAGX,MAAMa,EAAe,EACnB,qBAAqBb,GAAe,WAAa,SAAS,GAC1D,CACE,QAASA,GAAe,OAAA,CAE5B,EAEA,OACEA,GAAe,WACfY,EAAmB,SAASZ,GAAe,SAAS,EAE7C,EAAE,wCAAyC,CAChD,QAASA,EAAc,OAAA,CACxB,EACQa,GAAgBA,EAAa,OAAS,EACxCA,EAEAb,EAAc,SAAW,EAAE,4BAA4B,CAElE,EAEA,MAAO,CAAE,wBAAAT,CAAwB,CACnC"}