@developer_tribe/react-native-comnyx 0.16.0 → 0.16.1
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/lib/commonjs/components/ChatList.js +39 -45
- package/lib/commonjs/components/ChatList.js.map +1 -1
- package/lib/commonjs/components/CustomerForm.js +5 -1
- package/lib/commonjs/components/CustomerForm.js.map +1 -1
- package/lib/commonjs/components/InitFailed.js +77 -21
- package/lib/commonjs/components/InitFailed.js.map +1 -1
- package/lib/commonjs/components/MediaMessageItem.js +33 -7
- package/lib/commonjs/components/MediaMessageItem.js.map +1 -1
- package/lib/commonjs/components/MediaViewerModal.js +16 -3
- package/lib/commonjs/components/MediaViewerModal.js.map +1 -1
- package/lib/commonjs/components/MessageInput.js +20 -2
- package/lib/commonjs/components/MessageInput.js.map +1 -1
- package/lib/commonjs/hooks/usePolling.js +5 -0
- package/lib/commonjs/hooks/usePolling.js.map +1 -1
- package/lib/commonjs/index.js +6 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/register/login.js +5 -0
- package/lib/commonjs/register/login.js.map +1 -1
- package/lib/commonjs/support/ComnyxSupport.js +31 -15
- package/lib/commonjs/support/ComnyxSupport.js.map +1 -1
- package/lib/commonjs/support/SupportConfigContext.js +42 -0
- package/lib/commonjs/support/SupportConfigContext.js.map +1 -1
- package/lib/commonjs/support/index.js +7 -0
- package/lib/commonjs/support/index.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/module/components/ChatList.js +40 -46
- package/lib/module/components/ChatList.js.map +1 -1
- package/lib/module/components/CustomerForm.js +5 -1
- package/lib/module/components/CustomerForm.js.map +1 -1
- package/lib/module/components/InitFailed.js +79 -23
- package/lib/module/components/InitFailed.js.map +1 -1
- package/lib/module/components/MediaMessageItem.js +33 -8
- package/lib/module/components/MediaMessageItem.js.map +1 -1
- package/lib/module/components/MediaViewerModal.js +15 -3
- package/lib/module/components/MediaViewerModal.js.map +1 -1
- package/lib/module/components/MessageInput.js +21 -3
- package/lib/module/components/MessageInput.js.map +1 -1
- package/lib/module/hooks/usePolling.js +5 -0
- package/lib/module/hooks/usePolling.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/register/login.js +5 -0
- package/lib/module/register/login.js.map +1 -1
- package/lib/module/support/ComnyxSupport.js +33 -17
- package/lib/module/support/ComnyxSupport.js.map +1 -1
- package/lib/module/support/SupportConfigContext.js +40 -0
- package/lib/module/support/SupportConfigContext.js.map +1 -1
- package/lib/module/support/index.js +1 -0
- package/lib/module/support/index.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/components/ChatList.d.ts.map +1 -1
- package/lib/typescript/src/components/CustomerForm.d.ts.map +1 -1
- package/lib/typescript/src/components/InitFailed.d.ts +5 -2
- package/lib/typescript/src/components/InitFailed.d.ts.map +1 -1
- package/lib/typescript/src/components/MediaMessageItem.d.ts.map +1 -1
- package/lib/typescript/src/components/MediaViewerModal.d.ts.map +1 -1
- package/lib/typescript/src/components/MessageInput.d.ts.map +1 -1
- package/lib/typescript/src/hooks/usePolling.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/register/login.d.ts.map +1 -1
- package/lib/typescript/src/support/ComnyxSupport.d.ts +26 -3
- package/lib/typescript/src/support/ComnyxSupport.d.ts.map +1 -1
- package/lib/typescript/src/support/SupportConfigContext.d.ts +40 -0
- package/lib/typescript/src/support/SupportConfigContext.d.ts.map +1 -1
- package/lib/typescript/src/support/index.d.ts +2 -1
- package/lib/typescript/src/support/index.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +10 -8
- package/src/components/ChatList.tsx +33 -45
- package/src/components/CustomerForm.tsx +5 -1
- package/src/components/InitFailed.tsx +80 -16
- package/src/components/MediaMessageItem.tsx +38 -8
- package/src/components/MediaViewerModal.tsx +21 -8
- package/src/components/MessageInput.tsx +20 -2
- package/src/hooks/usePolling.ts +5 -0
- package/src/index.ts +4 -0
- package/src/register/login.ts +5 -0
- package/src/support/ComnyxSupport.tsx +57 -14
- package/src/support/SupportConfigContext.tsx +78 -0
- package/src/support/index.ts +4 -0
- package/src/version.ts +1 -1
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
StatusBar,
|
|
7
7
|
useWindowDimensions,
|
|
8
8
|
} from 'react-native';
|
|
9
|
+
import FastImage from '@d11/react-native-fast-image';
|
|
9
10
|
import { useState, useEffect } from 'react';
|
|
10
11
|
import { AppText } from './AppText';
|
|
11
12
|
import { ScaledSheet } from './ScaledSheet';
|
|
@@ -61,15 +62,27 @@ export function MediaViewerModal({
|
|
|
61
62
|
>
|
|
62
63
|
<AppText style={styles.closeIcon}>✕</AppText>
|
|
63
64
|
</TouchableOpacity>
|
|
64
|
-
<View style={[styles.mediaContainer, { width, height
|
|
65
|
+
<View style={[styles.mediaContainer, { width, height }]}>
|
|
65
66
|
{displayUri && !imageError ? (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
/^https?:\/\//i.test(displayUri) ? (
|
|
68
|
+
<FastImage
|
|
69
|
+
source={{
|
|
70
|
+
uri: displayUri,
|
|
71
|
+
cache: FastImage.cacheControl.immutable,
|
|
72
|
+
}}
|
|
73
|
+
style={{ width, height }}
|
|
74
|
+
resizeMode={FastImage.resizeMode.contain}
|
|
75
|
+
onError={() => setImageError(true)}
|
|
76
|
+
/>
|
|
77
|
+
) : (
|
|
78
|
+
<Image
|
|
79
|
+
source={{ uri: displayUri }}
|
|
80
|
+
style={{ width, height }}
|
|
81
|
+
resizeMode="contain"
|
|
82
|
+
resizeMethod="resize"
|
|
83
|
+
onError={() => setImageError(true)}
|
|
84
|
+
/>
|
|
85
|
+
)
|
|
73
86
|
) : (
|
|
74
87
|
<View
|
|
75
88
|
style={[
|
|
@@ -17,7 +17,10 @@ import { useIsRtl } from '../hooks/isRtl';
|
|
|
17
17
|
import { useAppStore } from '../store/store';
|
|
18
18
|
import { MediaPickerButton } from './MediaPickerButton';
|
|
19
19
|
import type { MediaAsset } from '../types/MediaTypes';
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
useSupportConfig,
|
|
22
|
+
reportSupportError,
|
|
23
|
+
} from '../support/SupportConfigContext';
|
|
21
24
|
|
|
22
25
|
const sendDark = require('../assets/arrow-right.png');
|
|
23
26
|
const circleXIcon = require('../assets/x-circle.png');
|
|
@@ -100,7 +103,7 @@ export function MessageInput({
|
|
|
100
103
|
//TODO: ??
|
|
101
104
|
}
|
|
102
105
|
})
|
|
103
|
-
.catch(() => {
|
|
106
|
+
.catch((err) => {
|
|
104
107
|
const data = useAppStore.getState().data;
|
|
105
108
|
if (data) {
|
|
106
109
|
const itemIndex = data.findIndex((item) => item.local_id === localId);
|
|
@@ -125,6 +128,11 @@ export function MessageInput({
|
|
|
125
128
|
} else {
|
|
126
129
|
//TODO: ??
|
|
127
130
|
}
|
|
131
|
+
reportSupportError(err, {
|
|
132
|
+
section: 'send',
|
|
133
|
+
recoverable: true,
|
|
134
|
+
extras: { contentLength: value.length },
|
|
135
|
+
});
|
|
128
136
|
});
|
|
129
137
|
setValue('');
|
|
130
138
|
}, [value, customer, scrollToBottom]);
|
|
@@ -296,6 +304,15 @@ export function MessageInput({
|
|
|
296
304
|
}
|
|
297
305
|
}
|
|
298
306
|
console.error('[Comnyx] Media upload failed:', error);
|
|
307
|
+
reportSupportError(error, {
|
|
308
|
+
section: 'upload',
|
|
309
|
+
recoverable: true,
|
|
310
|
+
extras: {
|
|
311
|
+
assetCount: assets.length,
|
|
312
|
+
mediaTypes: assets.map((a) => a.type),
|
|
313
|
+
aborted: controller.signal.aborted,
|
|
314
|
+
},
|
|
315
|
+
});
|
|
299
316
|
} finally {
|
|
300
317
|
if (uploadAbortRef.current === controller) {
|
|
301
318
|
uploadAbortRef.current = null;
|
|
@@ -454,6 +471,7 @@ export function MessageInput({
|
|
|
454
471
|
<Image
|
|
455
472
|
style={[
|
|
456
473
|
styles.sendIcon,
|
|
474
|
+
{ tintColor: themeColors.text },
|
|
457
475
|
isRtl && { transform: [{ rotate: '180deg' }] },
|
|
458
476
|
isSending && { opacity: 0.4 },
|
|
459
477
|
]}
|
package/src/hooks/usePolling.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { getNewCustomerConversation } from '../api';
|
|
3
3
|
import { useAppStore } from '../store/store';
|
|
4
|
+
import { reportSupportError } from '../support/SupportConfigContext';
|
|
4
5
|
|
|
5
6
|
const NEW_MESSAGES_CHECK_INTERVAL = 10000;
|
|
6
7
|
|
|
@@ -45,6 +46,10 @@ export function usePolling() {
|
|
|
45
46
|
.catch((err) => {
|
|
46
47
|
if (controller.signal.aborted) return;
|
|
47
48
|
console.warn('[Comnyx] Polling failed:', err);
|
|
49
|
+
reportSupportError(err, {
|
|
50
|
+
section: 'polling',
|
|
51
|
+
recoverable: true,
|
|
52
|
+
});
|
|
48
53
|
});
|
|
49
54
|
}, NEW_MESSAGES_CHECK_INTERVAL);
|
|
50
55
|
|
package/src/index.ts
CHANGED
|
@@ -16,7 +16,11 @@ export type {
|
|
|
16
16
|
SupportErrorRenderProps,
|
|
17
17
|
SupportMessageRenderProps,
|
|
18
18
|
SupportSendPayload,
|
|
19
|
+
SupportErrorSection,
|
|
20
|
+
SupportErrorContext,
|
|
21
|
+
SupportErrorReporter,
|
|
19
22
|
} from './support';
|
|
23
|
+
export { ComnyxErrorBoundary } from './support';
|
|
20
24
|
|
|
21
25
|
//deprecated
|
|
22
26
|
export { registerOneSignalForComnyx } from './register/collectData';
|
package/src/register/login.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { isInitCalled, setLoginForAxios } from '../api/api';
|
|
|
3
3
|
import type { CreateCustomerRequest } from '../types/Customer';
|
|
4
4
|
import { useAppStore } from '../store/store';
|
|
5
5
|
import { updateCustomer } from '../api/customers';
|
|
6
|
+
import { reportSupportError } from '../support/SupportConfigContext';
|
|
6
7
|
|
|
7
8
|
interface LoginOptions {
|
|
8
9
|
externalId: string;
|
|
@@ -27,6 +28,10 @@ export function login(loginOptions: LoginOptions) {
|
|
|
27
28
|
useAppStore.getState().setCustomer(data.customer);
|
|
28
29
|
} catch (error) {
|
|
29
30
|
console.error('[Comnyx] Error in login', error);
|
|
31
|
+
reportSupportError(error, {
|
|
32
|
+
section: 'init',
|
|
33
|
+
recoverable: false,
|
|
34
|
+
});
|
|
30
35
|
}
|
|
31
36
|
});
|
|
32
37
|
}
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
View,
|
|
3
3
|
TouchableOpacity,
|
|
4
4
|
Image,
|
|
5
|
+
Appearance,
|
|
5
6
|
type ViewStyle,
|
|
6
7
|
type StyleProp,
|
|
7
8
|
} from 'react-native';
|
|
@@ -21,15 +22,21 @@ import { accumulator } from '../register/Accumulator';
|
|
|
21
22
|
import {
|
|
22
23
|
SupportConfigProvider,
|
|
23
24
|
type SupportConfig,
|
|
25
|
+
setGlobalSupportErrorReporter,
|
|
26
|
+
reportSupportError,
|
|
24
27
|
} from './SupportConfigContext';
|
|
25
|
-
import { ComnyxErrorBoundary } from '../components/ComnyxErrorBoundary';
|
|
26
28
|
const closeIcon = require('../assets/x-close.png');
|
|
27
29
|
|
|
28
30
|
interface SupportComnyxProps {
|
|
29
31
|
/** Language code used for localised UI strings. Defaults to `'en'`. */
|
|
30
32
|
language?: LanguageCode;
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Colour palette mode. Defaults to `'dark'`.
|
|
35
|
+
*
|
|
36
|
+
* Pass `'system'` to follow the OS colour scheme — the palette flips
|
|
37
|
+
* automatically when the user toggles dark/light at the system level.
|
|
38
|
+
*/
|
|
39
|
+
theme?: 'light' | 'dark' | 'system';
|
|
33
40
|
/** Render the chat in fake/demo mode (no network). */
|
|
34
41
|
fake?: boolean;
|
|
35
42
|
/** Called when the user taps the close button. */
|
|
@@ -84,9 +91,27 @@ interface SupportComnyxProps {
|
|
|
84
91
|
* Use for analytics, rate limiting, moderation or injecting extra context.
|
|
85
92
|
*/
|
|
86
93
|
onBeforeSend?: SupportConfig['onBeforeSend'];
|
|
94
|
+
/**
|
|
95
|
+
* Receives non-render operational errors caught inside the SDK (network
|
|
96
|
+
* failures, polling errors, upload crashes, customer-form submit errors).
|
|
97
|
+
* Wire to your host's error tracker — typically `Bugsnag.notify`:
|
|
98
|
+
*
|
|
99
|
+
* ```tsx
|
|
100
|
+
* onError={(err, ctx) => {
|
|
101
|
+
* if (err instanceof Error) {
|
|
102
|
+
* Bugsnag.notify(err, (event) => event.addMetadata('comnyx', ctx));
|
|
103
|
+
* }
|
|
104
|
+
* }}
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* Render-time exceptions intentionally bubble to your root React error
|
|
108
|
+
* boundary (e.g. `@bugsnag/plugin-react`) so the existing crash reporting
|
|
109
|
+
* path keeps working unchanged.
|
|
110
|
+
*/
|
|
111
|
+
onError?: SupportConfig['onError'];
|
|
87
112
|
}
|
|
88
113
|
|
|
89
|
-
function
|
|
114
|
+
export function ComnyxSupport({
|
|
90
115
|
language = 'en',
|
|
91
116
|
theme = 'dark',
|
|
92
117
|
fake = false,
|
|
@@ -99,6 +124,7 @@ function ComnyxSupportInner({
|
|
|
99
124
|
renderErrorState,
|
|
100
125
|
renderMessage,
|
|
101
126
|
onBeforeSend,
|
|
127
|
+
onError,
|
|
102
128
|
}: SupportComnyxProps) {
|
|
103
129
|
const { customer, formSubmitted } = useAppStore((s) => ({
|
|
104
130
|
customer: s.customer,
|
|
@@ -116,6 +142,7 @@ function ComnyxSupportInner({
|
|
|
116
142
|
renderErrorState,
|
|
117
143
|
renderMessage,
|
|
118
144
|
onBeforeSend,
|
|
145
|
+
onError,
|
|
119
146
|
}),
|
|
120
147
|
[
|
|
121
148
|
renderHeader,
|
|
@@ -123,9 +150,17 @@ function ComnyxSupportInner({
|
|
|
123
150
|
renderErrorState,
|
|
124
151
|
renderMessage,
|
|
125
152
|
onBeforeSend,
|
|
153
|
+
onError,
|
|
126
154
|
]
|
|
127
155
|
);
|
|
128
156
|
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
setGlobalSupportErrorReporter(onError);
|
|
159
|
+
return () => {
|
|
160
|
+
setGlobalSupportErrorReporter(undefined);
|
|
161
|
+
};
|
|
162
|
+
}, [onError]);
|
|
163
|
+
|
|
129
164
|
useEffect(() => {
|
|
130
165
|
if (!accumulator.isListenerCalledOnce()) {
|
|
131
166
|
accumulator
|
|
@@ -137,6 +172,10 @@ function ComnyxSupportInner({
|
|
|
137
172
|
})
|
|
138
173
|
.catch((err) => {
|
|
139
174
|
console.error('[Comnyx] accumulator.flush failed', err);
|
|
175
|
+
reportSupportError(err, {
|
|
176
|
+
section: 'accumulator',
|
|
177
|
+
recoverable: true,
|
|
178
|
+
});
|
|
140
179
|
setInitLoading(false);
|
|
141
180
|
});
|
|
142
181
|
} else {
|
|
@@ -152,7 +191,6 @@ function ComnyxSupportInner({
|
|
|
152
191
|
|
|
153
192
|
useEffect(() => {
|
|
154
193
|
useAppStore.getState().setLanguage(language);
|
|
155
|
-
useAppStore.getState().setTheme(theme);
|
|
156
194
|
useAppStore.getState().setFake(fake);
|
|
157
195
|
if (themes) {
|
|
158
196
|
useAppStore.getState().setThemes(themes);
|
|
@@ -160,7 +198,20 @@ function ComnyxSupportInner({
|
|
|
160
198
|
if (themeOverride) {
|
|
161
199
|
useAppStore.getState().setThemeOverride(themeOverride);
|
|
162
200
|
}
|
|
163
|
-
}, [language,
|
|
201
|
+
}, [language, fake, themes, themeOverride]);
|
|
202
|
+
|
|
203
|
+
useEffect(() => {
|
|
204
|
+
const setTheme = useAppStore.getState().setTheme;
|
|
205
|
+
if (theme !== 'system') {
|
|
206
|
+
setTheme(theme);
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
setTheme(Appearance.getColorScheme() === 'dark' ? 'dark' : 'light');
|
|
210
|
+
const sub = Appearance.addChangeListener(({ colorScheme }) => {
|
|
211
|
+
setTheme(colorScheme === 'dark' ? 'dark' : 'light');
|
|
212
|
+
});
|
|
213
|
+
return () => sub.remove();
|
|
214
|
+
}, [theme]);
|
|
164
215
|
|
|
165
216
|
let body: ReactElement;
|
|
166
217
|
if (!customer) {
|
|
@@ -216,14 +267,6 @@ function ComnyxSupportInner({
|
|
|
216
267
|
);
|
|
217
268
|
}
|
|
218
269
|
|
|
219
|
-
export function ComnyxSupport(props: SupportComnyxProps) {
|
|
220
|
-
return (
|
|
221
|
-
<ComnyxErrorBoundary onBack={props.onBack}>
|
|
222
|
-
<ComnyxSupportInner {...props} />
|
|
223
|
-
</ComnyxErrorBoundary>
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
270
|
const styles = ScaledSheet.create({
|
|
228
271
|
container: {
|
|
229
272
|
flex: 1,
|
|
@@ -26,6 +26,52 @@ export interface SupportSendPayload {
|
|
|
26
26
|
mediaTypes: Array<'image' | 'video'>;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Where inside the SDK an error originated. Helpful for dashboard grouping
|
|
31
|
+
* and for deciding which errors are user-visible vs silent.
|
|
32
|
+
*/
|
|
33
|
+
export type SupportErrorSection =
|
|
34
|
+
| 'init'
|
|
35
|
+
| 'pagination'
|
|
36
|
+
| 'polling'
|
|
37
|
+
| 'send'
|
|
38
|
+
| 'upload'
|
|
39
|
+
| 'media-picker'
|
|
40
|
+
| 'customer-form'
|
|
41
|
+
| 'accumulator';
|
|
42
|
+
|
|
43
|
+
export interface SupportErrorContext {
|
|
44
|
+
/** Which subsystem the error came from. */
|
|
45
|
+
section: SupportErrorSection;
|
|
46
|
+
/**
|
|
47
|
+
* True when the SDK already recovered (e.g. surfaced a retry affordance to
|
|
48
|
+
* the user). False for fire-and-forget failures worth investigating.
|
|
49
|
+
*/
|
|
50
|
+
recoverable: boolean;
|
|
51
|
+
/** Additional structured context — usage varies per section. */
|
|
52
|
+
extras?: Record<string, unknown>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Called whenever the SDK catches an operational error it cannot surface
|
|
57
|
+
* itself. Wire this to your error tracker — for Bugsnag:
|
|
58
|
+
*
|
|
59
|
+
* ```tsx
|
|
60
|
+
* onError={(err, ctx) => {
|
|
61
|
+
* if (err instanceof Error) {
|
|
62
|
+
* Bugsnag.notify(err, (event) => event.addMetadata('comnyx', ctx));
|
|
63
|
+
* }
|
|
64
|
+
* }}
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* Render-time exceptions are intentionally NOT funnelled here — they bubble
|
|
68
|
+
* to the host's React error boundary so `@bugsnag/plugin-react` sees them.
|
|
69
|
+
*/
|
|
70
|
+
export type SupportErrorReporter = (
|
|
71
|
+
error: unknown,
|
|
72
|
+
context: SupportErrorContext
|
|
73
|
+
) => void;
|
|
74
|
+
|
|
29
75
|
export interface SupportConfig {
|
|
30
76
|
/**
|
|
31
77
|
* Replace the built-in top header (close button + "Support team / Live" row).
|
|
@@ -54,6 +100,12 @@ export interface SupportConfig {
|
|
|
54
100
|
* Use for analytics, rate limiting, moderation, or injecting extra context.
|
|
55
101
|
*/
|
|
56
102
|
onBeforeSend?: (payload: SupportSendPayload) => void | Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Receives non-render operational errors the SDK catches internally. Route
|
|
105
|
+
* to your host's error tracker (e.g. `Bugsnag.notify`) so failures are not
|
|
106
|
+
* silently swallowed to the console.
|
|
107
|
+
*/
|
|
108
|
+
onError?: SupportErrorReporter;
|
|
57
109
|
}
|
|
58
110
|
|
|
59
111
|
const EMPTY_CONFIG: SupportConfig = {};
|
|
@@ -77,3 +129,29 @@ export function SupportConfigProvider({
|
|
|
77
129
|
export function useSupportConfig(): SupportConfig {
|
|
78
130
|
return useContext(SupportConfigContext);
|
|
79
131
|
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Module-level error forwarder so hooks that run outside of a render pass
|
|
135
|
+
* (accumulator.flush, polling tick) can still report. Set once per mount.
|
|
136
|
+
*/
|
|
137
|
+
let globalErrorReporter: SupportErrorReporter | undefined;
|
|
138
|
+
|
|
139
|
+
export function setGlobalSupportErrorReporter(
|
|
140
|
+
reporter: SupportErrorReporter | undefined
|
|
141
|
+
) {
|
|
142
|
+
globalErrorReporter = reporter;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function reportSupportError(
|
|
146
|
+
error: unknown,
|
|
147
|
+
context: SupportErrorContext
|
|
148
|
+
) {
|
|
149
|
+
if (globalErrorReporter) {
|
|
150
|
+
try {
|
|
151
|
+
globalErrorReporter(error, context);
|
|
152
|
+
} catch (reporterErr) {
|
|
153
|
+
// Never let a broken reporter take down the SDK.
|
|
154
|
+
console.error('[Comnyx] onError reporter threw:', reporterErr);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
package/src/support/index.ts
CHANGED
|
@@ -5,4 +5,8 @@ export type {
|
|
|
5
5
|
SupportErrorRenderProps,
|
|
6
6
|
SupportMessageRenderProps,
|
|
7
7
|
SupportSendPayload,
|
|
8
|
+
SupportErrorSection,
|
|
9
|
+
SupportErrorContext,
|
|
10
|
+
SupportErrorReporter,
|
|
8
11
|
} from './SupportConfigContext';
|
|
12
|
+
export { ComnyxErrorBoundary } from '../components/ComnyxErrorBoundary';
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated. Do not edit manually.
|
|
2
|
-
export const VERSION = '0.16.
|
|
2
|
+
export const VERSION = '0.16.1';
|