@laravel/stream-react 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,26 +49,23 @@ function App() {
49
49
 
50
50
  When sending data back to the stream, the active connection to the stream is canceled before sending the new data. All requests are sent as JSON `POST` requests.
51
51
 
52
- The second argument given to `useStream` is an options object that you may use to customize the stream consumption behavior. The default values for this object are shown below:
53
-
54
- ```tsx
55
- import { useStream } from "@laravel/stream-react";
56
-
57
- function App() {
58
- const { data } = useStream("chat", {
59
- id: undefined,
60
- initialInput: undefined,
61
- headers: undefined,
62
- csrfToken: undefined,
63
- onResponse: (response: Response) => void,
64
- onData: (data: string) => void,
65
- onCancel: () => void,
66
- onFinish: () => void,
67
- onError: (error: Error) => void,
68
- });
69
-
70
- return <div>{data}</div>;
71
- }
52
+ The second argument given to `useStream` is an options object that you may use to customize the stream consumption behavior:
53
+
54
+ ```ts
55
+ type StreamOptions = {
56
+ id?: string;
57
+ initialInput?: Record<string, any>;
58
+ headers?: Record<string, string>;
59
+ csrfToken?: string;
60
+ json?: boolean;
61
+ credentials?: RequestCredentials;
62
+ onResponse?: (response: Response) => void;
63
+ onData?: (data: string) => void;
64
+ onCancel?: () => void;
65
+ onFinish?: () => void;
66
+ onError?: (error: Error) => void;
67
+ onBeforeSend?: (request: RequestInit) => boolean | RequestInit | void;
68
+ };
72
69
  ```
73
70
 
74
71
  `onResponse` is triggered after a successful initial response from the stream and the raw [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) is passed to the callback.
@@ -77,6 +74,8 @@ function App() {
77
74
 
78
75
  `onFinish` is called when a stream has finished and when an error is thrown during the fetch/read cycle.
79
76
 
77
+ `onBeforeSend` is called right before sending the request to the server and receives the `RequestInit` object as an argument. Returning `false` from this callback cancels the request, returning a [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit) object will override the existing `RequestInit` object.
78
+
80
79
  By default, a request is not made the to stream on initialization. You may pass an initial payload to the stream by using the `initialInput` option:
81
80
 
82
81
  ```tsx
package/dist/index.d.ts CHANGED
@@ -21,11 +21,13 @@ declare type StreamOptions = {
21
21
  headers?: Record<string, string>;
22
22
  csrfToken?: string;
23
23
  json?: boolean;
24
+ credentials?: RequestCredentials;
24
25
  onResponse?: (response: Response) => void;
25
26
  onData?: (data: string) => void;
26
27
  onCancel?: () => void;
27
28
  onFinish?: () => void;
28
29
  onError?: (error: Error) => void;
30
+ onBeforeSend?: (request: RequestInit) => RequestInit | boolean | void;
29
31
  };
30
32
 
31
33
  /**
package/dist/index.es.js CHANGED
@@ -1,56 +1,106 @@
1
- import { useRef as j, useMemo as V, useState as y, useCallback as o, useEffect as M } from "react";
2
- const I = "data: ", Q = (r, {
1
+ import { useRef as j, useMemo as K, useState as C, useCallback as u, useEffect as k } from "react";
2
+ const q = "data: ", ee = (r, {
3
3
  eventName: e = "update",
4
4
  endSignal: n = "</stream>",
5
- glue: c = " ",
6
- replace: b = !1,
5
+ glue: t = " ",
6
+ replace: l = !1,
7
7
  onMessage: T = () => null,
8
- onComplete: k = () => null,
9
- onError: P = () => null
8
+ onComplete: P = () => null,
9
+ onError: I = () => null
10
10
  } = {}) => {
11
- const i = j(null), g = j([]), w = V(
11
+ const i = j(null), h = j([]), E = K(
12
12
  () => Array.isArray(e) ? e : [e],
13
13
  Array.isArray(e) ? e : [e]
14
- ), [D, A] = y(""), [d, f] = y([]), h = o(() => {
15
- g.current = [], A(""), f([]);
16
- }, []), E = o(
17
- (t) => {
18
- if ([n, `${I}${n}`].includes(t.data)) {
19
- S(), k();
14
+ ), [F, B] = C(""), [f, d] = C([]), g = u(() => {
15
+ h.current = [], B(""), d([]);
16
+ }, []), D = u(
17
+ (s) => {
18
+ if ([n, `${q}${n}`].includes(s.data)) {
19
+ S(), P();
20
20
  return;
21
21
  }
22
- b && h(), g.current.push(
23
- t.data.startsWith(I) ? t.data.substring(I.length) : t.data
24
- ), A(g.current.join(c)), f(g.current), T(t);
22
+ l && g(), h.current.push(
23
+ s.data.startsWith(q) ? s.data.substring(q.length) : s.data
24
+ ), B(h.current.join(t)), d(h.current), T(s);
25
25
  },
26
- [w, c]
27
- ), F = o((t) => {
28
- P(t), S();
29
- }, []), S = o((t = !1) => {
30
- var a, s;
31
- w.forEach((u) => {
32
- var l;
33
- (l = i.current) == null || l.removeEventListener(u, E);
34
- }), (a = i.current) == null || a.removeEventListener("error", F), (s = i.current) == null || s.close(), i.current = null, t && h();
26
+ [E, t]
27
+ ), R = u((s) => {
28
+ I(s), S();
29
+ }, []), S = u((s = !1) => {
30
+ var a, c;
31
+ E.forEach((b) => {
32
+ var o;
33
+ (o = i.current) == null || o.removeEventListener(b, D);
34
+ }), (a = i.current) == null || a.removeEventListener("error", R), (c = i.current) == null || c.close(), i.current = null, s && g();
35
35
  }, []);
36
- return M(() => (h(), i.current = new EventSource(r), w.forEach((t) => {
36
+ return k(() => (g(), i.current = new EventSource(r), E.forEach((s) => {
37
37
  var a;
38
- (a = i.current) == null || a.addEventListener(t, E);
39
- }), i.current.addEventListener("error", F), S), [r, w, E, F, h]), {
40
- message: D,
41
- messageParts: d,
38
+ (a = i.current) == null || a.addEventListener(s, D);
39
+ }), i.current.addEventListener("error", R), S), [r, E, D, R, g]), {
40
+ message: F,
41
+ messageParts: f,
42
42
  close: S,
43
- clearMessage: h
43
+ clearMessage: g
44
44
  };
45
- }, W = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
46
- let $ = (r = 21) => {
45
+ }, V = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
46
+ let W = (r = 21) => {
47
47
  let e = "", n = crypto.getRandomValues(new Uint8Array(r |= 0));
48
48
  for (; r--; )
49
- e += W[n[r] & 63];
49
+ e += V[n[r] & 63];
50
50
  return e;
51
51
  };
52
- const C = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), R = (r) => {
53
- const e = C.get(r);
52
+ const A = /* @__PURE__ */ new Map(), $ = (r, e) => {
53
+ A.has(r) || A.set(r, {
54
+ onData: [],
55
+ onError: [],
56
+ onFinish: [],
57
+ onResponse: [],
58
+ onCancel: [],
59
+ onBeforeSend: []
60
+ });
61
+ const n = A.get(r);
62
+ 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), () => {
63
+ Z(r, e);
64
+ };
65
+ }, w = (r, e, ...n) => {
66
+ const t = A.get(r);
67
+ return t ? t[e].map((l) => l(...n)) : [];
68
+ }, x = (r) => {
69
+ w(r, "onFinish");
70
+ }, J = (r, e) => {
71
+ w(r, "onError", e);
72
+ }, G = (r, e) => {
73
+ w(r, "onResponse", e);
74
+ }, H = (r) => {
75
+ w(r, "onCancel");
76
+ }, Q = (r, e) => {
77
+ w(r, "onData", e);
78
+ }, Y = (r, e) => {
79
+ const n = w(r, "onBeforeSend", e);
80
+ for (const t of n) {
81
+ if (t === !1)
82
+ return !1;
83
+ if (t !== null && typeof t == "object")
84
+ return t;
85
+ }
86
+ return null;
87
+ }, Z = (r, e) => {
88
+ const n = A.get(r);
89
+ n && (e.onData && (n.onData = n.onData.filter(
90
+ (t) => t !== e.onData
91
+ )), e.onError && (n.onError = n.onError.filter(
92
+ (t) => t !== e.onError
93
+ )), e.onFinish && (n.onFinish = n.onFinish.filter(
94
+ (t) => t !== e.onFinish
95
+ )), e.onResponse && (n.onResponse = n.onResponse.filter(
96
+ (t) => t !== e.onResponse
97
+ )), e.onCancel && (n.onCancel = n.onCancel.filter(
98
+ (t) => t !== e.onCancel
99
+ )), e.onBeforeSend && (n.onBeforeSend = n.onBeforeSend.filter(
100
+ (t) => t !== e.onBeforeSend
101
+ )));
102
+ }, M = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), v = (r) => {
103
+ const e = M.get(r);
54
104
  if (e)
55
105
  return e;
56
106
  const n = {
@@ -60,143 +110,147 @@ const C = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), R = (r) => {
60
110
  isStreaming: !1,
61
111
  jsonData: null
62
112
  };
63
- return C.set(r, n), n;
64
- }, q = (r) => (m.has(r) || m.set(r, []), m.get(r)), X = (r) => {
113
+ return M.set(r, n), n;
114
+ }, O = (r) => (m.has(r) || m.set(r, []), m.get(r)), p = (r) => {
65
115
  var e;
66
116
  return m.has(r) && ((e = m.get(r)) == null ? void 0 : e.length);
67
- }, B = (r, e) => (q(r).push(e), () => {
117
+ }, _ = (r, e) => (O(r).push(e), () => {
68
118
  m.set(
69
119
  r,
70
- q(r).filter((n) => n !== e)
71
- ), X(r) || (C.delete(r), m.delete(r));
72
- }), G = (r, e = {}) => {
73
- const n = j(e.id ?? $()), c = j(R(n.current)), b = j(
120
+ O(r).filter((n) => n !== e)
121
+ ), p(r) || (M.delete(r), m.delete(r));
122
+ }), N = (r, e) => {
123
+ var t;
124
+ M.set(r, {
125
+ ...v(r),
126
+ ...e
127
+ });
128
+ const n = v(r);
129
+ (t = m.get(r)) == null || t.forEach((l) => l(n));
130
+ }, z = (r, e = {}) => {
131
+ const n = j(e.id ?? W()), t = j(v(n.current)), l = j(
74
132
  (() => {
75
- var s;
76
- const t = {
133
+ var c;
134
+ const s = {
77
135
  "Content-Type": "application/json",
78
136
  "X-STREAM-ID": n.current
79
- }, a = e.csrfToken ?? ((s = document.querySelector('meta[name="csrf-token"]')) == null ? void 0 : s.getAttribute("content"));
80
- return a && (t["X-CSRF-TOKEN"] = a), t;
137
+ }, a = e.csrfToken ?? ((c = document.querySelector('meta[name="csrf-token"]')) == null ? void 0 : c.getAttribute("content"));
138
+ return a && (s["X-CSRF-TOKEN"] = a), s;
81
139
  })()
82
- ), [T, k] = y(c.current.data), [P, i] = y(
83
- c.current.jsonData
84
- ), [g, w] = y(c.current.isFetching), [D, A] = y(c.current.isStreaming), d = o(
85
- (t) => {
86
- var s;
87
- C.set(n.current, {
88
- ...R(n.current),
89
- ...t
90
- });
91
- const a = R(n.current);
92
- (s = m.get(n.current)) == null || s.forEach((u) => u(a));
140
+ ), [T, P] = C(t.current.data), [I, i] = C(
141
+ t.current.jsonData
142
+ ), [h, E] = C(t.current.isFetching), [F, B] = C(t.current.isStreaming), f = u(
143
+ (s) => {
144
+ N(n.current, s);
93
145
  },
94
146
  []
95
- ), f = o(() => {
96
- var t;
97
- c.current.controller.abort(), (g || D) && ((t = e.onCancel) == null || t.call(e)), d({
147
+ ), d = u(() => {
148
+ t.current.controller.abort(), (h || F) && H(n.current), f({
98
149
  isFetching: !1,
99
150
  isStreaming: !1
100
151
  });
101
- }, [g, D]), h = o(() => {
102
- d({
152
+ }, [h, F]), g = u(() => {
153
+ f({
103
154
  data: "",
104
155
  jsonData: null
105
156
  });
106
- }, []), E = o(
107
- (t = {}) => {
108
- const a = new AbortController();
109
- d({
110
- isFetching: !0,
111
- controller: a
112
- }), fetch(r, {
157
+ }, []), D = u(
158
+ (s = {}) => {
159
+ const a = new AbortController(), c = {
113
160
  method: "POST",
114
161
  signal: a.signal,
115
162
  headers: {
116
- ...b.current,
163
+ ...l.current,
117
164
  ...e.headers ?? {}
118
165
  },
119
- body: JSON.stringify(t)
120
- }).then(async (s) => {
121
- var u;
122
- if (!s.ok) {
123
- const l = await s.text();
124
- throw new Error(l);
166
+ body: JSON.stringify(s),
167
+ credentials: e.credentials ?? "same-origin"
168
+ }, b = Y(n.current, c);
169
+ b !== !1 && (f({
170
+ isFetching: !0,
171
+ controller: a
172
+ }), fetch(r, b ?? c).then(async (o) => {
173
+ if (!o.ok) {
174
+ const y = await o.text();
175
+ throw new Error(y);
125
176
  }
126
- if (!s.body)
177
+ if (!o.body)
127
178
  throw new Error(
128
179
  "ReadableStream not yet supported in this browser."
129
180
  );
130
- return (u = e.onResponse) == null || u.call(e, s), d({
181
+ return G(n.current, o), f({
131
182
  isFetching: !1,
132
183
  isStreaming: !0
133
- }), S(s.body.getReader());
134
- }).catch((s) => {
135
- var u, l;
136
- d({
184
+ }), S(o.body.getReader());
185
+ }).catch((o) => {
186
+ f({
137
187
  isFetching: !1,
138
188
  isStreaming: !1
139
- }), (u = e.onError) == null || u.call(e, s), (l = e.onFinish) == null || l.call(e);
140
- });
189
+ }), J(n.current, o), x(n.current);
190
+ }));
141
191
  },
142
192
  [r]
143
- ), F = o((t) => {
144
- f(), E(t), h();
145
- }, []), S = o(
146
- (t, a = "") => t.read().then(({ done: s, value: u }) => {
147
- var x, J, O;
148
- const l = new TextDecoder("utf-8").decode(u), v = a + l;
149
- (x = e.onData) == null || x.call(e, l);
193
+ ), R = u((s) => {
194
+ d(), D(s), g();
195
+ }, []), S = u(
196
+ (s, a = "") => s.read().then(({ done: c, value: b }) => {
197
+ const o = new TextDecoder("utf-8").decode(b), y = a + o;
198
+ Q(n.current, o);
150
199
  const L = {
151
- data: v
200
+ data: y
152
201
  };
153
- if (!s)
154
- return d(L), S(t, v);
202
+ if (!c)
203
+ return f(L), S(s, y);
155
204
  if (L.isStreaming = !1, e.json)
156
205
  try {
157
206
  L.jsonData = JSON.parse(
158
- v
207
+ y
159
208
  );
160
- } catch (K) {
161
- (J = e.onError) == null || J.call(e, K);
209
+ } catch (X) {
210
+ J(n.current, X);
162
211
  }
163
- return d(L), (O = e.onFinish) == null || O.call(e), "";
212
+ return f(L), x(n.current), "";
164
213
  }),
165
214
  []
166
215
  );
167
- return M(() => {
168
- const t = B(
216
+ return k(() => {
217
+ const s = _(
169
218
  n.current,
170
219
  (a) => {
171
- c.current = R(n.current), w(a.isFetching), A(a.isStreaming), k(a.data), i(a.jsonData);
220
+ t.current = v(n.current), E(a.isFetching), B(a.isStreaming), P(a.data), i(a.jsonData);
172
221
  }
173
222
  );
174
223
  return () => {
175
- t(), X(n.current) || f();
224
+ s(), p(n.current) || d();
225
+ };
226
+ }, []), k(() => {
227
+ const s = $(n.current, e);
228
+ return () => {
229
+ s();
176
230
  };
177
- }, []), M(() => (window.addEventListener("beforeunload", f), () => {
178
- window.removeEventListener("beforeunload", f);
179
- }), [f]), M(() => {
180
- e.initialInput && E(e.initialInput);
231
+ }, [e]), k(() => (window.addEventListener("beforeunload", d), () => {
232
+ window.removeEventListener("beforeunload", d);
233
+ }), [d]), k(() => {
234
+ e.initialInput && D(e.initialInput);
181
235
  }, []), {
182
236
  data: T,
183
- jsonData: P,
184
- isFetching: g,
185
- isStreaming: D,
237
+ jsonData: I,
238
+ isFetching: h,
239
+ isStreaming: F,
186
240
  id: n.current,
187
- send: F,
188
- cancel: f,
189
- clearData: h
241
+ send: R,
242
+ cancel: d,
243
+ clearData: g
190
244
  };
191
- }, Y = (r, e = {}) => {
192
- const { jsonData: n, data: c, ...b } = G(r, {
245
+ }, ne = (r, e = {}) => {
246
+ const { jsonData: n, data: t, ...l } = z(r, {
193
247
  ...e,
194
248
  json: !0
195
249
  });
196
- return { data: n, strData: c, ...b };
250
+ return { data: n, strData: t, ...l };
197
251
  };
198
252
  export {
199
- Q as useEventStream,
200
- Y as useJsonStream,
201
- G as useStream
253
+ ee as useEventStream,
254
+ ne as useJsonStream,
255
+ z as useStream
202
256
  };
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- (function(i,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],t):(i=typeof globalThis<"u"?globalThis:i||self,t(i.LaravelStreamReact={},i.React))})(this,function(i,t){"use strict";const L="data: ",X=(r,{eventName:e="update",endSignal:s="</stream>",glue:c=" ",replace:y=!1,onMessage:A=()=>null,onComplete:M=()=>null,onError:T=()=>null}={})=>{const o=t.useRef(null),m=t.useRef([]),E=t.useMemo(()=>Array.isArray(e)?e:[e],Array.isArray(e)?e:[e]),[C,j]=t.useState(""),[d,h]=t.useState([]),S=t.useCallback(()=>{m.current=[],j(""),h([])},[]),w=t.useCallback(n=>{if([s,`${L}${s}`].includes(n.data)){b(),M();return}y&&S(),m.current.push(n.data.startsWith(L)?n.data.substring(L.length):n.data),j(m.current.join(c)),h(m.current),A(n)},[E,c]),R=t.useCallback(n=>{T(n),b()},[]),b=t.useCallback((n=!1)=>{var a,u;E.forEach(l=>{var f;(f=o.current)==null||f.removeEventListener(l,w)}),(a=o.current)==null||a.removeEventListener("error",R),(u=o.current)==null||u.close(),o.current=null,n&&S()},[]);return t.useEffect(()=>(S(),o.current=new EventSource(r),E.forEach(n=>{var a;(a=o.current)==null||a.addEventListener(n,w)}),o.current.addEventListener("error",R),b),[r,E,w,R,S]),{message:C,messageParts:d,close:b,clearMessage:S}},K="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";let V=(r=21)=>{let e="",s=crypto.getRandomValues(new Uint8Array(r|=0));for(;r--;)e+=K[s[r]&63];return e};const k=new Map,g=new Map,D=r=>{const e=k.get(r);if(e)return e;const s={controller:new AbortController,data:"",isFetching:!1,isStreaming:!1,jsonData:null};return k.set(r,s),s},P=r=>(g.has(r)||g.set(r,[]),g.get(r)),I=r=>{var e;return g.has(r)&&((e=g.get(r))==null?void 0:e.length)},W=(r,e)=>(P(r).push(e),()=>{g.set(r,P(r).filter(s=>s!==e)),I(r)||(k.delete(r),g.delete(r))}),J=(r,e={})=>{const s=t.useRef(e.id??V()),c=t.useRef(D(s.current)),y=t.useRef((()=>{var u;const n={"Content-Type":"application/json","X-STREAM-ID":s.current},a=e.csrfToken??((u=document.querySelector('meta[name="csrf-token"]'))==null?void 0:u.getAttribute("content"));return a&&(n["X-CSRF-TOKEN"]=a),n})()),[A,M]=t.useState(c.current.data),[T,o]=t.useState(c.current.jsonData),[m,E]=t.useState(c.current.isFetching),[C,j]=t.useState(c.current.isStreaming),d=t.useCallback(n=>{var u;k.set(s.current,{...D(s.current),...n});const a=D(s.current);(u=g.get(s.current))==null||u.forEach(l=>l(a))},[]),h=t.useCallback(()=>{var n;c.current.controller.abort(),(m||C)&&((n=e.onCancel)==null||n.call(e)),d({isFetching:!1,isStreaming:!1})},[m,C]),S=t.useCallback(()=>{d({data:"",jsonData:null})},[]),w=t.useCallback((n={})=>{const a=new AbortController;d({isFetching:!0,controller:a}),fetch(r,{method:"POST",signal:a.signal,headers:{...y.current,...e.headers??{}},body:JSON.stringify(n)}).then(async u=>{var l;if(!u.ok){const f=await u.text();throw new Error(f)}if(!u.body)throw new Error("ReadableStream not yet supported in this browser.");return(l=e.onResponse)==null||l.call(e,u),d({isFetching:!1,isStreaming:!0}),b(u.body.getReader())}).catch(u=>{var l,f;d({isFetching:!1,isStreaming:!1}),(l=e.onError)==null||l.call(e,u),(f=e.onFinish)==null||f.call(e)})},[r]),R=t.useCallback(n=>{h(),w(n),S()},[]),b=t.useCallback((n,a="")=>n.read().then(({done:u,value:l})=>{var O,q,x;const f=new TextDecoder("utf-8").decode(l),v=a+f;(O=e.onData)==null||O.call(e,f);const F={data:v};if(!u)return d(F),b(n,v);if(F.isStreaming=!1,e.json)try{F.jsonData=JSON.parse(v)}catch(B){(q=e.onError)==null||q.call(e,B)}return d(F),(x=e.onFinish)==null||x.call(e),""}),[]);return t.useEffect(()=>{const n=W(s.current,a=>{c.current=D(s.current),E(a.isFetching),j(a.isStreaming),M(a.data),o(a.jsonData)});return()=>{n(),I(s.current)||h()}},[]),t.useEffect(()=>(window.addEventListener("beforeunload",h),()=>{window.removeEventListener("beforeunload",h)}),[h]),t.useEffect(()=>{e.initialInput&&w(e.initialInput)},[]),{data:A,jsonData:T,isFetching:m,isStreaming:C,id:s.current,send:R,cancel:h,clearData:S}},$=(r,e={})=>{const{jsonData:s,data:c,...y}=J(r,{...e,json:!0});return{data:s,strData:c,...y}};i.useEventStream=X,i.useJsonStream=$,i.useStream=J,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
1
+ (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"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laravel/stream-react",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Laravel streaming hooks for React",
5
5
  "keywords": [
6
6
  "laravel",