UNPKG

@laravel/stream-react

Version:
2 lines (1 loc) 5.34 kB
(function(l,s){typeof exports=="object"&&typeof module<"u"?s(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],s):(l=typeof globalThis<"u"?globalThis:l||self,s(l.LaravelStreamReact={},l.React))})(this,function(l,s){"use strict";const A="data: ",x=(t,{eventName:e="update",endSignal:n="</stream>",glue:r=" ",replace:i=!1,onMessage:B=()=>null,onComplete:T=()=>null,onError:P=()=>null}={})=>{const f=s.useRef(null),m=s.useRef([]),C=s.useMemo(()=>Array.isArray(e)?e:[e],Array.isArray(e)?e:[e]),[w,M]=s.useState(""),[d,h]=s.useState([]),g=s.useCallback(()=>{m.current=[],M(""),h([])},[]),R=s.useCallback(a=>{if([n,`${A}${n}`].includes(a.data)){b(),T();return}i&&g(),m.current.push(a.data.startsWith(A)?a.data.substring(A.length):a.data),M(m.current.join(r)),h(m.current),B(a)},[C,r]),y=s.useCallback(a=>{P(a),b()},[]),b=s.useCallback((a=!1)=>{var o,u;C.forEach(D=>{var c;(c=f.current)==null||c.removeEventListener(D,R)}),(o=f.current)==null||o.removeEventListener("error",y),(u=f.current)==null||u.close(),f.current=null,a&&g()},[]);return s.useEffect(()=>(g(),f.current=new EventSource(t),C.forEach(a=>{var o;(o=f.current)==null||o.addEventListener(a,R)}),f.current.addEventListener("error",y),b),[t,C,R,y,g]),{message:w,messageParts:d,close:b,clearMessage:g}},X="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";let K=(t=21)=>{let e="",n=crypto.getRandomValues(new Uint8Array(t|=0));for(;t--;)e+=X[n[t]&63];return e};const k=new Map,V=(t,e)=>{k.has(t)||k.set(t,{onData:[],onError:[],onFinish:[],onResponse:[],onCancel:[],onBeforeSend:[]});const n=k.get(t);return e.onData&&n.onData.push(e.onData),e.onError&&n.onError.push(e.onError),e.onFinish&&n.onFinish.push(e.onFinish),e.onResponse&&n.onResponse.push(e.onResponse),e.onCancel&&n.onCancel.push(e.onCancel),e.onBeforeSend&&n.onBeforeSend.push(e.onBeforeSend),()=>{Q(t,e)}},E=(t,e,...n)=>{const r=k.get(t);return r?r[e].map(i=>i(...n)):[]},p=t=>{E(t,"onFinish")},q=(t,e)=>{E(t,"onError",e)},W=(t,e)=>{E(t,"onResponse",e)},$=t=>{E(t,"onCancel")},G=(t,e)=>{E(t,"onData",e)},H=(t,e)=>{const n=E(t,"onBeforeSend",e);for(const r of n){if(r===!1)return!1;if(r!==null&&typeof r=="object")return r}return null},Q=(t,e)=>{const n=k.get(t);n&&(e.onData&&(n.onData=n.onData.filter(r=>r!==e.onData)),e.onError&&(n.onError=n.onError.filter(r=>r!==e.onError)),e.onFinish&&(n.onFinish=n.onFinish.filter(r=>r!==e.onFinish)),e.onResponse&&(n.onResponse=n.onResponse.filter(r=>r!==e.onResponse)),e.onCancel&&(n.onCancel=n.onCancel.filter(r=>r!==e.onCancel)),e.onBeforeSend&&(n.onBeforeSend=n.onBeforeSend.filter(r=>r!==e.onBeforeSend)))},j=new Map,S=new Map,L=t=>{const e=j.get(t);if(e)return e;const n={controller:new AbortController,data:"",isFetching:!1,isStreaming:!1,jsonData:null};return j.set(t,n),n},I=t=>(S.has(t)||S.set(t,[]),S.get(t)),J=t=>{var e;return S.has(t)&&((e=S.get(t))==null?void 0:e.length)},Y=(t,e)=>(I(t).push(e),()=>{S.set(t,I(t).filter(n=>n!==e)),J(t)||(j.delete(t),S.delete(t))}),Z=(t,e)=>{var r;j.set(t,{...L(t),...e});const n=L(t);(r=S.get(t))==null||r.forEach(i=>i(n))},O=(t,e={})=>{const n=s.useRef(e.id??K()),r=s.useRef(L(n.current)),i=s.useRef((()=>{var u;const a={"Content-Type":"application/json","X-STREAM-ID":n.current},o=e.csrfToken??((u=document.querySelector('meta[name="csrf-token"]'))==null?void 0:u.getAttribute("content"));return o&&(a["X-CSRF-TOKEN"]=o),a})()),[B,T]=s.useState(r.current.data),[P,f]=s.useState(r.current.jsonData),[m,C]=s.useState(r.current.isFetching),[w,M]=s.useState(r.current.isStreaming),d=s.useCallback(a=>{Z(n.current,a)},[]),h=s.useCallback(()=>{r.current.controller.abort(),(m||w)&&$(n.current),d({isFetching:!1,isStreaming:!1})},[m,w]),g=s.useCallback(()=>{d({data:"",jsonData:null})},[]),R=s.useCallback(a=>{const o=new AbortController,u={method:"POST",signal:o.signal,headers:{...i.current,...e.headers??{}},body:JSON.stringify(a??{}),credentials:e.credentials??"same-origin"},D=H(n.current,u);D!==!1&&(d({isFetching:!0,controller:o}),fetch(t,D??u).then(async c=>{if(!c.ok){const F=await c.text();throw new Error(F)}if(!c.body)throw new Error("ReadableStream not yet supported in this browser.");return W(n.current,c),d({isFetching:!1,isStreaming:!0}),b(c.body.getReader())}).catch(c=>{d({isFetching:!1,isStreaming:!1}),q(n.current,c),p(n.current)}))},[t]),y=s.useCallback(a=>{h(),R(a),g()},[]),b=s.useCallback((a,o="")=>a.read().then(({done:u,value:D})=>{const c=new TextDecoder("utf-8").decode(D),F=o+c;G(n.current,c);const v={data:F};if(!u)return d(v),b(a,F);if(v.isStreaming=!1,e.json)try{v.jsonData=JSON.parse(F)}catch(N){q(n.current,N)}return d(v),p(n.current),""}),[]);return s.useEffect(()=>{const a=Y(n.current,o=>{r.current=L(n.current),C(o.isFetching),M(o.isStreaming),T(o.data),f(o.jsonData)});return()=>{a(),J(n.current)||h()}},[]),s.useEffect(()=>{const a=V(n.current,e);return()=>{a()}},[e]),s.useEffect(()=>(window.addEventListener("beforeunload",h),()=>{window.removeEventListener("beforeunload",h)}),[h]),s.useEffect(()=>{e.initialInput&&R(e.initialInput)},[]),{data:B,jsonData:P,isFetching:m,isStreaming:w,id:n.current,send:y,cancel:h,clearData:g}},_=(t,e={})=>{const{jsonData:n,data:r,...i}=O(t,{...e,json:!0});return{data:n,strData:r,...i}};l.useEventStream=x,l.useJsonStream=_,l.useStream=O,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});