@sparrowdesk/react-chat 0.1.0 → 0.1.2

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/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import * as React$1 from "react";
1
+ import * as React from "react";
2
+ import { FC } from "react";
2
3
  import * as react_jsx_runtime0 from "react/jsx-runtime";
3
4
 
4
5
  //#region src/internal/sparrowDeskWidget.d.ts
@@ -76,7 +77,7 @@ interface ChatProps {
76
77
  */
77
78
  readyTimeoutMs?: number;
78
79
  }
79
- declare const Chat: React.FC<ChatProps>;
80
+ declare const Chat: FC<ChatProps>;
80
81
  //#endregion
81
82
  //#region src/SparrowDeskProvider.d.ts
82
83
  type SparrowDeskProviderProps = {
@@ -84,7 +85,7 @@ type SparrowDeskProviderProps = {
84
85
  domain: string;
85
86
  /** SparrowDesk widget token */
86
87
  token: string;
87
- children: React$1.ReactNode;
88
+ children: React.ReactNode;
88
89
  /**
89
90
  * Controls whether this provider should set globals and inject the widget script.
90
91
  * Set to `false` if SparrowDesk is loaded elsewhere (e.g. via Segment) and you only
package/dist/index.js CHANGED
@@ -1,400 +1 @@
1
- import * as React from "react";
2
- import { useEffect, useMemo, useRef, useState } from "react";
3
- import { jsx } from "react/jsx-runtime";
4
-
5
- //#region src/internal/sparrowDeskWidget.ts
6
- const DEFAULT_SCRIPT_SRC = "https://assets.cdn.sparrowdesk.com/chatbot/bundle/main.js";
7
- const DEFAULT_READY_TIMEOUT_MS = 1e4;
8
- const WIDGET_SCRIPT_SELECTOR = "script[data-sd-chat-widget=\"true\"]";
9
- function isBrowser() {
10
- return globalThis.document !== void 0;
11
- }
12
- function normalizeRequired(value) {
13
- return value.trim();
14
- }
15
- function setWidgetGlobals(domain, token) {
16
- const w = globalThis;
17
- w.SD_WIDGET_DOMAIN = domain;
18
- w.SD_WIDGET_TOKEN = token;
19
- }
20
- const scriptEntriesBySrc = /* @__PURE__ */ new Map();
21
- function removeOtherWidgetScripts(keepSrc) {
22
- document.querySelectorAll(WIDGET_SCRIPT_SELECTOR).forEach((script) => {
23
- if (script.src !== keepSrc) script.remove();
24
- });
25
- }
26
- function acquireWidgetScript(src, cleanupOnUnmount) {
27
- const cached = scriptEntriesBySrc.get(src);
28
- if (cached) {
29
- cached.refCount += 1;
30
- cached.cleanupWhenUnused ||= cleanupOnUnmount;
31
- return { release() {
32
- cached.refCount -= 1;
33
- if (cached.refCount > 0) return;
34
- if (cached.cleanupWhenUnused) cached.script.remove();
35
- scriptEntriesBySrc.delete(src);
36
- } };
37
- }
38
- const existing = document.querySelector(WIDGET_SCRIPT_SELECTOR);
39
- const entry = {
40
- script: existing?.src === src ? existing : (() => {
41
- const el = document.createElement("script");
42
- el.async = true;
43
- el.src = src;
44
- el.dataset["sdChatWidget"] = "true";
45
- document.body.appendChild(el);
46
- return el;
47
- })(),
48
- refCount: 1,
49
- cleanupWhenUnused: cleanupOnUnmount
50
- };
51
- scriptEntriesBySrc.set(src, entry);
52
- return { release() {
53
- entry.refCount -= 1;
54
- if (entry.refCount > 0) return;
55
- if (entry.cleanupWhenUnused) entry.script.remove();
56
- scriptEntriesBySrc.delete(src);
57
- } };
58
- }
59
- async function waitForSparrowDeskApi(timeoutMs) {
60
- const w = globalThis;
61
- if (w.sparrowDesk) return w.sparrowDesk;
62
- if (timeoutMs <= 0) return null;
63
- const startedAt = Date.now();
64
- while (Date.now() - startedAt < timeoutMs) {
65
- if (w.sparrowDesk) return w.sparrowDesk;
66
- await new Promise((r) => setTimeout(r, 50));
67
- }
68
- return null;
69
- }
70
-
71
- //#endregion
72
- //#region src/internal/useLatest.ts
73
- function useLatest(value) {
74
- const ref = useRef(value);
75
- useEffect(() => {
76
- ref.current = value;
77
- }, [value]);
78
- return ref;
79
- }
80
-
81
- //#endregion
82
- //#region src/Chat.tsx
83
- const Chat = ({ domain, token, tags, contactFields, conversationFields, onReady, onOpen, onClose, openOnInit = false, hideOnInit = false, shouldInitialize = true, connectOnPageLoad = true, initializeOnInteraction = true, cleanupOnUnmount = false, readyTimeoutMs = DEFAULT_READY_TIMEOUT_MS }) => {
84
- const normalized = useMemo(() => {
85
- return {
86
- domain: normalizeRequired(domain),
87
- token: normalizeRequired(token)
88
- };
89
- }, [domain, token]);
90
- const onOpenRef = useLatest(onOpen);
91
- const onCloseRef = useLatest(onClose);
92
- const onReadyRef = useLatest(onReady);
93
- const tagsRef = useLatest(tags);
94
- const contactFieldsRef = useLatest(contactFields);
95
- const conversationFieldsRef = useLatest(conversationFields);
96
- const registeredCallbacksRef = useRef(false);
97
- const apiRef = useRef(null);
98
- const didOpenOnceRef = useRef(false);
99
- const didHideOnceRef = useRef(false);
100
- const [shouldStart, setShouldStart] = useState(connectOnPageLoad);
101
- useEffect(() => {
102
- didOpenOnceRef.current = false;
103
- didHideOnceRef.current = false;
104
- apiRef.current = null;
105
- registeredCallbacksRef.current = false;
106
- setShouldStart(connectOnPageLoad);
107
- }, [normalized.domain, normalized.token]);
108
- useEffect(() => {
109
- if (!isBrowser()) return;
110
- if (!normalized.domain || !normalized.token) return;
111
- setWidgetGlobals(normalized.domain, normalized.token);
112
- if (!shouldInitialize) return;
113
- if (!shouldStart) return;
114
- removeOtherWidgetScripts(DEFAULT_SCRIPT_SRC);
115
- const handle = acquireWidgetScript(DEFAULT_SCRIPT_SRC, cleanupOnUnmount);
116
- return () => {
117
- handle.release();
118
- };
119
- }, [
120
- normalized.domain,
121
- normalized.token,
122
- cleanupOnUnmount,
123
- shouldInitialize,
124
- shouldStart
125
- ]);
126
- useEffect(() => {
127
- if (!isBrowser()) return;
128
- if (!normalized.domain || !normalized.token) return;
129
- if (!shouldStart) return;
130
- let cancelled = false;
131
- (async () => {
132
- const api = await waitForSparrowDeskApi(readyTimeoutMs);
133
- if (cancelled || !api) return;
134
- apiRef.current = api;
135
- if (!registeredCallbacksRef.current) {
136
- api.onOpen?.(() => onOpenRef.current?.());
137
- api.onClose?.(() => onCloseRef.current?.());
138
- registeredCallbacksRef.current = true;
139
- }
140
- onReadyRef.current?.(api);
141
- const latestTags = tagsRef.current;
142
- const latestContactFields = contactFieldsRef.current;
143
- const latestConversationFields = conversationFieldsRef.current;
144
- if (Array.isArray(latestTags) && latestTags.length) api.setTags?.(latestTags);
145
- if (latestContactFields && Object.keys(latestContactFields).length) api.setContactFields?.(latestContactFields);
146
- if (latestConversationFields && Object.keys(latestConversationFields).length) api.setConversationFields?.(latestConversationFields);
147
- if (hideOnInit && !didHideOnceRef.current) {
148
- api.hideWidget?.();
149
- didHideOnceRef.current = true;
150
- }
151
- if (openOnInit && !didOpenOnceRef.current) {
152
- api.openWidget?.();
153
- didOpenOnceRef.current = true;
154
- }
155
- })();
156
- return () => {
157
- cancelled = true;
158
- };
159
- }, [
160
- normalized.domain,
161
- normalized.token,
162
- openOnInit,
163
- hideOnInit,
164
- readyTimeoutMs,
165
- shouldStart
166
- ]);
167
- useEffect(() => {
168
- if (!isBrowser()) return;
169
- if (connectOnPageLoad) return;
170
- if (!initializeOnInteraction) return;
171
- if (shouldStart) return;
172
- if (!normalized.domain || !normalized.token) return;
173
- const onFirstInteraction = () => {
174
- setShouldStart(true);
175
- cleanup();
176
- };
177
- const cleanup = () => {
178
- document.removeEventListener("pointerdown", onFirstInteraction, true);
179
- document.removeEventListener("keydown", onFirstInteraction, true);
180
- };
181
- document.addEventListener("pointerdown", onFirstInteraction, true);
182
- document.addEventListener("keydown", onFirstInteraction, true);
183
- return cleanup;
184
- }, [
185
- connectOnPageLoad,
186
- initializeOnInteraction,
187
- normalized.domain,
188
- normalized.token,
189
- shouldStart
190
- ]);
191
- useEffect(() => {
192
- const api = apiRef.current;
193
- if (!api) return;
194
- if (Array.isArray(tags) && tags.length) api.setTags?.(tags);
195
- if (contactFields && Object.keys(contactFields).length) api.setContactFields?.(contactFields);
196
- if (conversationFields && Object.keys(conversationFields).length) api.setConversationFields?.(conversationFields);
197
- }, [
198
- tags,
199
- contactFields,
200
- conversationFields
201
- ]);
202
- if (!normalized.domain || !normalized.token) return null;
203
- return /* @__PURE__ */ jsx("div", { "data-sd-chat-widget-container": "" });
204
- };
205
-
206
- //#endregion
207
- //#region src/SparrowDeskProvider.tsx
208
- const SparrowDeskContext = React.createContext(null);
209
- function useSparrowDesk() {
210
- const value = React.useContext(SparrowDeskContext);
211
- if (!value) throw new Error("useSparrowDesk must be used within <SparrowDeskProvider />");
212
- return value;
213
- }
214
- function SparrowDeskProvider({ domain, token, children, shouldInitialize = true, connectOnPageLoad = true, initializeOnInteraction = true, tags, contactFields, conversationFields, onReady, onOpen, onClose, openOnInit = false, hideOnInit = false, cleanupOnUnmount = false, readyTimeoutMs = DEFAULT_READY_TIMEOUT_MS }) {
215
- const normalized = useMemo(() => {
216
- return {
217
- domain: normalizeRequired(domain),
218
- token: normalizeRequired(token)
219
- };
220
- }, [domain, token]);
221
- const onReadyRef = useLatest(onReady);
222
- const onOpenRef = useLatest(onOpen);
223
- const onCloseRef = useLatest(onClose);
224
- const tagsRef = useLatest(tags);
225
- const contactFieldsRef = useLatest(contactFields);
226
- const conversationFieldsRef = useLatest(conversationFields);
227
- const openOnInitRef = useLatest(openOnInit);
228
- const hideOnInitRef = useLatest(hideOnInit);
229
- const apiRef = useRef(null);
230
- const registeredCallbacksRef = useRef(false);
231
- const didOpenOnceRef = useRef(false);
232
- const didHideOnceRef = useRef(false);
233
- const scriptHandleRef = useRef(null);
234
- const initStartedRef = useRef(false);
235
- const initCancelRef = useRef(null);
236
- const pendingCallsRef = useRef([]);
237
- const [isReady, setIsReady] = useState(false);
238
- const [shouldStart, setShouldStart] = useState(connectOnPageLoad);
239
- useEffect(() => {
240
- setShouldStart(connectOnPageLoad);
241
- }, [connectOnPageLoad]);
242
- useEffect(() => {
243
- didOpenOnceRef.current = false;
244
- didHideOnceRef.current = false;
245
- apiRef.current = null;
246
- registeredCallbacksRef.current = false;
247
- initStartedRef.current = false;
248
- initCancelRef.current?.();
249
- initCancelRef.current = null;
250
- pendingCallsRef.current = [];
251
- scriptHandleRef.current?.release();
252
- scriptHandleRef.current = null;
253
- setIsReady(false);
254
- setShouldStart(connectOnPageLoad);
255
- }, [
256
- normalized.domain,
257
- normalized.token,
258
- connectOnPageLoad
259
- ]);
260
- const initialize = React.useCallback(() => {
261
- if (!isBrowser()) return;
262
- if (!normalized.domain || !normalized.token) return;
263
- setWidgetGlobals(normalized.domain, normalized.token);
264
- if (shouldInitialize && !scriptHandleRef.current) {
265
- removeOtherWidgetScripts(DEFAULT_SCRIPT_SRC);
266
- scriptHandleRef.current = acquireWidgetScript(DEFAULT_SCRIPT_SRC, cleanupOnUnmount);
267
- }
268
- if (initStartedRef.current) return;
269
- initStartedRef.current = true;
270
- let cancelled = false;
271
- initCancelRef.current = () => {
272
- cancelled = true;
273
- };
274
- (async () => {
275
- const api = await waitForSparrowDeskApi(readyTimeoutMs);
276
- if (cancelled || !api) return;
277
- apiRef.current = api;
278
- setIsReady(true);
279
- if (!registeredCallbacksRef.current) {
280
- api.onOpen?.(() => onOpenRef.current?.());
281
- api.onClose?.(() => onCloseRef.current?.());
282
- registeredCallbacksRef.current = true;
283
- }
284
- onReadyRef.current?.(api);
285
- const latestTags = tagsRef.current;
286
- const latestContactFields = contactFieldsRef.current;
287
- const latestConversationFields = conversationFieldsRef.current;
288
- if (Array.isArray(latestTags) && latestTags.length) api.setTags?.(latestTags);
289
- if (latestContactFields && Object.keys(latestContactFields).length) api.setContactFields?.(latestContactFields);
290
- if (latestConversationFields && Object.keys(latestConversationFields).length) api.setConversationFields?.(latestConversationFields);
291
- if (hideOnInitRef.current && !didHideOnceRef.current) {
292
- api.hideWidget?.();
293
- didHideOnceRef.current = true;
294
- }
295
- if (openOnInitRef.current && !didOpenOnceRef.current) {
296
- api.openWidget?.();
297
- didOpenOnceRef.current = true;
298
- }
299
- const pending = pendingCallsRef.current;
300
- pendingCallsRef.current = [];
301
- pending.forEach((fn) => fn(api));
302
- })();
303
- }, [
304
- cleanupOnUnmount,
305
- normalized.domain,
306
- normalized.token,
307
- readyTimeoutMs,
308
- shouldInitialize
309
- ]);
310
- useEffect(() => {
311
- if (!isBrowser()) return;
312
- if (!normalized.domain || !normalized.token) return;
313
- setWidgetGlobals(normalized.domain, normalized.token);
314
- if (!shouldStart) return;
315
- initialize();
316
- return () => {
317
- initCancelRef.current?.();
318
- initCancelRef.current = null;
319
- if (!apiRef.current) initStartedRef.current = false;
320
- scriptHandleRef.current?.release();
321
- scriptHandleRef.current = null;
322
- };
323
- }, [
324
- initialize,
325
- normalized.domain,
326
- normalized.token,
327
- shouldStart
328
- ]);
329
- useEffect(() => {
330
- if (!isBrowser()) return;
331
- if (connectOnPageLoad) return;
332
- if (!initializeOnInteraction) return;
333
- if (shouldStart) return;
334
- if (!normalized.domain || !normalized.token) return;
335
- const onFirstInteraction = () => {
336
- setShouldStart(true);
337
- cleanup();
338
- };
339
- const cleanup = () => {
340
- document.removeEventListener("pointerdown", onFirstInteraction, true);
341
- document.removeEventListener("keydown", onFirstInteraction, true);
342
- };
343
- document.addEventListener("pointerdown", onFirstInteraction, true);
344
- document.addEventListener("keydown", onFirstInteraction, true);
345
- return cleanup;
346
- }, [
347
- connectOnPageLoad,
348
- initializeOnInteraction,
349
- normalized.domain,
350
- normalized.token,
351
- shouldStart
352
- ]);
353
- useEffect(() => {
354
- const api = apiRef.current;
355
- if (!api) return;
356
- if (Array.isArray(tags) && tags.length) api.setTags?.(tags);
357
- if (contactFields && Object.keys(contactFields).length) api.setContactFields?.(contactFields);
358
- if (conversationFields && Object.keys(conversationFields).length) api.setConversationFields?.(conversationFields);
359
- }, [
360
- tags,
361
- contactFields,
362
- conversationFields
363
- ]);
364
- const methods = useMemo(() => {
365
- const callOrQueue = (fn) => {
366
- const api = apiRef.current;
367
- if (api) {
368
- fn(api);
369
- return;
370
- }
371
- if (!connectOnPageLoad) {
372
- initialize();
373
- pendingCallsRef.current.push(fn);
374
- }
375
- };
376
- return {
377
- initialize,
378
- openWidget: () => callOrQueue((api) => api.openWidget?.()),
379
- closeWidget: () => callOrQueue((api) => api.closeWidget?.()),
380
- hideWidget: () => callOrQueue((api) => api.hideWidget?.()),
381
- setTags: (t) => callOrQueue((api) => api.setTags?.(t)),
382
- setContactFields: (f) => callOrQueue((api) => api.setContactFields?.(f)),
383
- setConversationFields: (f) => callOrQueue((api) => api.setConversationFields?.(f))
384
- };
385
- }, [connectOnPageLoad, initialize]);
386
- const value = useMemo(() => {
387
- return {
388
- ...methods,
389
- isReady,
390
- api: apiRef.current
391
- };
392
- }, [methods, isReady]);
393
- return /* @__PURE__ */ jsx(SparrowDeskContext.Provider, {
394
- value,
395
- children
396
- });
397
- }
398
-
399
- //#endregion
400
- export { Chat, SparrowDeskProvider, useSparrowDesk };
1
+ import*as e from"react";import{useEffect as t,useMemo as n,useRef as r,useState as i}from"react";import{jsx as a}from"react/jsx-runtime";const o=`https://assets.cdn.sparrowdesk.com/chatbot/bundle/main.js`,s=1e4,c=`script[data-sd-chat-widget="true"]`;function l(){return globalThis.document!==void 0}function u(e){return e.trim()}function d(e,t){let n=globalThis;n.SD_WIDGET_DOMAIN=e,n.SD_WIDGET_TOKEN=t}const f=new Map;function p(e){document.querySelectorAll(c).forEach(t=>{t.src!==e&&t.remove()})}function m(e,t){let n=f.get(e);if(n)return n.refCount+=1,{release(){--n.refCount,!(n.refCount>0)&&(t&&n.script.remove(),f.delete(e))}};let r=document.querySelector(c),i={script:r?.src===e?r:(()=>{let t=document.createElement(`script`);return t.async=!0,t.src=e,t.dataset.sdChatWidget=`true`,document.body.appendChild(t),t})(),refCount:1};return f.set(e,i),{release(){--i.refCount,!(i.refCount>0)&&(t&&i.script.remove(),f.delete(e))}}}async function h(e){let t=globalThis;if(t.sparrowDesk)return t.sparrowDesk;if(e<=0)return null;let n=Date.now();for(;Date.now()-n<e;){if(t.sparrowDesk)return t.sparrowDesk;await new Promise(e=>setTimeout(e,50))}return null}function g(e){let n=r(e);return t(()=>{n.current=e},[e]),n}const _=({domain:e,token:c,tags:f,contactFields:_,conversationFields:v,onReady:y,onOpen:b,onClose:x,openOnInit:S=!1,hideOnInit:C=!1,shouldInitialize:w=!0,connectOnPageLoad:T=!0,initializeOnInteraction:E=!0,cleanupOnUnmount:D=!1,readyTimeoutMs:O=s})=>{let k=n(()=>({domain:u(e),token:u(c)}),[e,c]),A=g(b),j=g(x),M=g(y),N=g(f),P=g(_),F=g(v),I=r(!1),L=r(null),R=r(!1),z=r(!1),[B,V]=i(T);return t(()=>{V(T)},[T]),t(()=>{R.current=!1,z.current=!1,L.current=null,I.current=!1,V(T)},[k.domain,k.token,T]),t(()=>{if(!l()||!k.domain||!k.token||(d(k.domain,k.token),!w)||!B)return;p(o);let e=m(o,D);return()=>{e.release()}},[k.domain,k.token,D,w,B]),t(()=>{if(!l()||!k.domain||!k.token||!B)return;let e=!1;return(async()=>{let t=await h(O);if(e||!t)return;L.current=t,I.current||=(t.onOpen?.(()=>A.current?.()),t.onClose?.(()=>j.current?.()),!0),M.current?.(t);let n=N.current,r=P.current,i=F.current;Array.isArray(n)&&n.length&&t.setTags?.(n),r&&Object.keys(r).length&&t.setContactFields?.(r),i&&Object.keys(i).length&&t.setConversationFields?.(i),C&&!z.current&&(t.hideWidget?.(),z.current=!0),S&&!R.current&&(t.openWidget?.(),R.current=!0)})(),()=>{e=!0}},[k.domain,k.token,S,C,O,B]),t(()=>{if(!l()||T||!E||B||!k.domain||!k.token)return;let e=()=>{V(!0),t()},t=()=>{document.removeEventListener(`pointerdown`,e,!0),document.removeEventListener(`keydown`,e,!0)};return document.addEventListener(`pointerdown`,e,!0),document.addEventListener(`keydown`,e,!0),t},[T,E,k.domain,k.token,B]),t(()=>{let e=L.current;e&&(Array.isArray(f)&&f.length&&e.setTags?.(f),_&&Object.keys(_).length&&e.setContactFields?.(_),v&&Object.keys(v).length&&e.setConversationFields?.(v))},[f,_,v]),!k.domain||!k.token?null:a(`div`,{"data-sd-chat-widget-container":``})},v=e.createContext(null);function y(){let t=e.useContext(v);if(!t)throw Error(`useSparrowDesk must be used within <SparrowDeskProvider />`);return t}function b({domain:c,token:f,children:_,shouldInitialize:y=!0,connectOnPageLoad:b=!0,initializeOnInteraction:x=!0,tags:S,contactFields:C,conversationFields:w,onReady:T,onOpen:E,onClose:D,openOnInit:O=!1,hideOnInit:k=!1,cleanupOnUnmount:A=!1,readyTimeoutMs:j=s}){let M=n(()=>({domain:u(c),token:u(f)}),[c,f]),N=g(T),P=g(E),F=g(D),I=g(S),L=g(C),R=g(w),z=g(O),B=g(k),V=r(null),H=r(!1),U=r(!1),W=r(!1),G=r(null),K=r(!1),q=r(null),J=r([]),[Y,X]=i(!1),[Z,Q]=i(b);t(()=>{Q(b)},[b]),t(()=>{U.current=!1,W.current=!1,V.current=null,H.current=!1,K.current=!1,q.current?.(),q.current=null,J.current=[],G.current?.release(),G.current=null,X(!1),Q(b)},[M.domain,M.token,b]);let $=e.useCallback(()=>{if(!l()||!M.domain||!M.token||(d(M.domain,M.token),y&&!G.current&&(p(o),G.current=m(o,A)),K.current))return;K.current=!0;let e=!1;q.current=()=>{e=!0},(async()=>{let t=await h(j);if(e||!t)return;V.current=t,X(!0),H.current||=(t.onOpen?.(()=>P.current?.()),t.onClose?.(()=>F.current?.()),!0),N.current?.(t);let n=I.current,r=L.current,i=R.current;Array.isArray(n)&&n.length&&t.setTags?.(n),r&&Object.keys(r).length&&t.setContactFields?.(r),i&&Object.keys(i).length&&t.setConversationFields?.(i),B.current&&!W.current&&(t.hideWidget?.(),W.current=!0),z.current&&!U.current&&(t.openWidget?.(),U.current=!0);let a=J.current;J.current=[],a.forEach(e=>e(t))})()},[A,M.domain,M.token,j,y]);t(()=>{if(l()&&!(!M.domain||!M.token)&&(d(M.domain,M.token),Z))return $(),()=>{q.current?.(),q.current=null,V.current||(K.current=!1),G.current?.release(),G.current=null}},[$,M.domain,M.token,Z]),t(()=>{if(!l()||b||!x||Z||!M.domain||!M.token)return;let e=()=>{Q(!0),t()},t=()=>{document.removeEventListener(`pointerdown`,e,!0),document.removeEventListener(`keydown`,e,!0)};return document.addEventListener(`pointerdown`,e,!0),document.addEventListener(`keydown`,e,!0),t},[b,x,M.domain,M.token,Z]),t(()=>{let e=V.current;e&&(Array.isArray(S)&&S.length&&e.setTags?.(S),C&&Object.keys(C).length&&e.setContactFields?.(C),w&&Object.keys(w).length&&e.setConversationFields?.(w))},[S,C,w]);let ee=n(()=>{let e=e=>{let t=V.current;if(t){e(t);return}$(),J.current.length<50&&J.current.push(e)};return{initialize:$,openWidget:()=>e(e=>e.openWidget?.()),closeWidget:()=>e(e=>e.closeWidget?.()),hideWidget:()=>e(e=>e.hideWidget?.()),setTags:t=>e(e=>e.setTags?.(t)),setContactFields:t=>e(e=>e.setContactFields?.(t)),setConversationFields:t=>e(e=>e.setConversationFields?.(t))}},[$]),te=n(()=>({...ee,isReady:Y,api:V.current}),[ee,Y]);return a(v.Provider,{value:te,children:_})}export{_ as Chat,b as SparrowDeskProvider,y as useSparrowDesk};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sparrowdesk/react-chat",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.1.2",
5
5
  "description": "SparrowDesk Chat Widget for React.",
6
6
  "keywords": [
7
7
  "sparrowdesk",
@@ -37,15 +37,6 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "scripts": {
41
- "build": "tsdown",
42
- "dev": "tsdown --watch",
43
- "test": "vitest run",
44
- "test:watch": "vitest",
45
- "typecheck": "tsc --noEmit",
46
- "release": "bumpp && pnpm publish",
47
- "prepublishOnly": "pnpm run build"
48
- },
49
40
  "peerDependencies": {
50
41
  "react": "^19.2.0",
51
42
  "react-dom": "^19.2.0"
@@ -64,5 +55,13 @@
64
55
  "typescript": "^5.9.3",
65
56
  "vitest": "^4.0.16",
66
57
  "vitest-browser-react": "^2.0.2"
58
+ },
59
+ "scripts": {
60
+ "build": "tsdown",
61
+ "dev": "tsdown --watch",
62
+ "test": "vitest run",
63
+ "test:watch": "vitest",
64
+ "typecheck": "tsc --noEmit",
65
+ "release": "bumpp && pnpm publish"
67
66
  }
68
- }
67
+ }