@bytexbyte/nxtlinq-ai-agent-sdk 1.6.8 → 1.6.9

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../../src/components/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,EACL,kBAAkB,EAClB,YAAY,EAGb,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CA+6DlD,CAAC"}
1
+ {"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../../src/components/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,EACL,kBAAkB,EAClB,YAAY,EAGb,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAs/DlD,CAAC"}
@@ -35,7 +35,7 @@ idvBannerDismissSeconds = 86400,
35
35
  isStopRecordingOnSend = false, }) => {
36
36
  const nxtlinqApi = React.useMemo(() => createNxtlinqApi(apiKey, apiSecret), [apiKey, apiSecret]);
37
37
  // Custom hook
38
- const { isRecording, transcript, start: startRecording, stop: stopRecording, clear: clearRecording } = useSpeechToTextFromMic({
38
+ const { isRecording, transcript, partialTranscript, start: startRecording, stop: stopRecording, clear: clearRecording } = useSpeechToTextFromMic({
39
39
  apiKey,
40
40
  apiSecret
41
41
  });
@@ -77,6 +77,40 @@ isStopRecordingOnSend = false, }) => {
77
77
  // Refs for input value and recording state
78
78
  const isRecordingRef = React.useRef(false);
79
79
  const textInputRef = React.useRef(null);
80
+ const lastPartialRangeRef = React.useRef(null);
81
+ function insertPartial(input, partial, caret) {
82
+ let start = caret;
83
+ let end = caret;
84
+ if (lastPartialRangeRef.current) {
85
+ start = lastPartialRangeRef.current.start;
86
+ end = lastPartialRangeRef.current.end;
87
+ }
88
+ const before = input.slice(0, start);
89
+ const after = input.slice(end);
90
+ const next = before + partial + after;
91
+ const newCaret = start + partial.length;
92
+ lastPartialRangeRef.current = { start, end: newCaret };
93
+ return { next, caret: newCaret };
94
+ }
95
+ function finalizePartial(input, finalText) {
96
+ if (!lastPartialRangeRef.current) {
97
+ return { next: input, caret: input.length };
98
+ }
99
+ const { start, end } = lastPartialRangeRef.current;
100
+ const before = input.slice(0, start);
101
+ const after = input.slice(end);
102
+ const next = before + finalText + after;
103
+ const caret = start + finalText.length;
104
+ lastPartialRangeRef.current = null;
105
+ return { next, caret };
106
+ }
107
+ function normalizeTranscript(text) {
108
+ return text
109
+ .toLowerCase()
110
+ .replace(/[.,!?;:]/g, '')
111
+ .replace(/\s+/g, ' ')
112
+ .trim();
113
+ }
80
114
  // Simple token cleanup function
81
115
  const clearExpiredToken = React.useCallback(() => {
82
116
  try {
@@ -104,10 +138,34 @@ isStopRecordingOnSend = false, }) => {
104
138
  signerRef.current = signer;
105
139
  }, [signer]);
106
140
  React.useEffect(() => {
107
- if (!transcript) {
141
+ if (!textInputRef.current)
108
142
  return;
143
+ const el = textInputRef.current;
144
+ const selStart = el.selectionStart ?? inputValue.length;
145
+ if (partialTranscript) {
146
+ const { next, caret } = insertPartial(inputValue, partialTranscript, selStart);
147
+ setInputValue(next);
148
+ setTimeout(() => {
149
+ if (textInputRef.current) {
150
+ textInputRef.current.selectionStart = caret;
151
+ textInputRef.current.selectionEnd = caret;
152
+ }
153
+ }, 0);
109
154
  }
110
- setInputValue(transcript);
155
+ }, [partialTranscript]);
156
+ React.useEffect(() => {
157
+ if (!transcript)
158
+ return;
159
+ if (!textInputRef.current)
160
+ return;
161
+ const { next, caret } = finalizePartial(inputValue, transcript);
162
+ setInputValue(normalizeTranscript(next));
163
+ setTimeout(() => {
164
+ if (textInputRef.current) {
165
+ textInputRef.current.selectionStart = caret;
166
+ textInputRef.current.selectionEnd = caret;
167
+ }
168
+ }, 0);
111
169
  }, [transcript]);
112
170
  React.useEffect(() => {
113
171
  isRecordingRef.current = isRecording;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageInput.d.ts","sourceRoot":"","sources":["../../../src/components/ui/MessageInput.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAqGhC,CAAC"}
1
+ {"version":3,"file":"MessageInput.d.ts","sourceRoot":"","sources":["../../../src/components/ui/MessageInput.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAoGhC,CAAC"}
@@ -24,7 +24,7 @@ export const MessageInput = () => {
24
24
  border-top: 1px solid #eee !important;
25
25
  `, children: [_jsx(InputBase, { value: inputValue, onChange: (e) => setInputValue(e.target.value), onKeyPress: handleKeyPress, placeholder: inputPlaceholder, fullWidth: true, inputProps: {
26
26
  ref: textInputRef
27
- }, endAdornment: _jsx(IconButton, { onClick: () => isRecording ? stopRecording() : startRecording(), children: isRecording ? _jsx(MicIcon, {}) : _jsx(MicOffIcon, {}) }), onFocus: () => stopRecording(), css: css `
27
+ }, endAdornment: _jsx(IconButton, { onClick: () => isRecording ? stopRecording() : startRecording(), children: isRecording ? _jsx(MicIcon, {}) : _jsx(MicOffIcon, {}) }), css: css `
28
28
  flex: 1 !important;
29
29
  padding: 10px !important;
30
30
  border: 1px solid #ddd !important;
@@ -1,12 +1,15 @@
1
1
  import { SpeechRecognizer } from 'microsoft-cognitiveservices-speech-sdk';
2
2
  import { Dispatch, SetStateAction } from 'react';
3
3
  /**
4
- * Start speech recognition, continuously updates speechToTextArray (each sentence as an array element)
4
+ * Start speech recognition
5
+ * - partialTranscript: 暫存逐字 (recognizing)
6
+ * - setSpeechToTextArray: 完整句子陣列 (recognized)
5
7
  */
6
- export declare const startSpeechToTextFromMic: (setSpeechToTextArray: Dispatch<SetStateAction<string[]>>, config: {
8
+ export declare const startSpeechToTextFromMic: (setSpeechToTextArray: Dispatch<SetStateAction<string[]>>, // 完整句子
9
+ config: {
7
10
  apiKey: string;
8
11
  apiSecret: string;
9
- }, historyRef: React.MutableRefObject<string[]>, indexRef: React.MutableRefObject<number>) => Promise<SpeechRecognizer | undefined>;
12
+ }, historyRef: React.MutableRefObject<string[]>, indexRef: React.MutableRefObject<number>, setPartialTranscript?: Dispatch<SetStateAction<string>>) => Promise<SpeechRecognizer | undefined>;
10
13
  /**
11
14
  * Stop speech recognition
12
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../../../src/core/lib/useSpeechToTextFromMic/helper.ts"],"names":[],"mappings":"AACA,OAAO,EAML,gBAAgB,EACjB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAMjD;;GAEG;AACH,eAAO,MAAM,wBAAwB,GACnC,sBAAsB,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,EACxD,QAAQ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7C,YAAY,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAC5C,UAAU,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,KACvC,OAAO,CAAC,gBAAgB,GAAG,SAAS,CA4CtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,YAAY,gBAAgB,GAAG,SAAS,SAIvE,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;GAwBxE"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../../../src/core/lib/useSpeechToTextFromMic/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,gBAAgB,EACjB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAIjD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,sBAAsB,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,EAAI,OAAO;AACnE,QAAQ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7C,YAAY,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAC5C,UAAU,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,EACxC,uBAAuB,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,KACtD,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAsDtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,YAAY,gBAAgB,GAAG,SAAS,SAIvE,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;GAwBxE"}
@@ -1,11 +1,14 @@
1
1
  import { AudioConfig, CancellationReason, PropertyId, ResultReason, SpeechConfig, SpeechRecognizer, } from 'microsoft-cognitiveservices-speech-sdk';
2
2
  import Cookie from 'universal-cookie';
3
3
  import { createNxtlinqApi } from '../../../api/nxtlinq-api';
4
- let recognizer;
5
4
  /**
6
- * Start speech recognition, continuously updates speechToTextArray (each sentence as an array element)
5
+ * Start speech recognition
6
+ * - partialTranscript: 暫存逐字 (recognizing)
7
+ * - setSpeechToTextArray: 完整句子陣列 (recognized)
7
8
  */
8
- export const startSpeechToTextFromMic = async (setSpeechToTextArray, config, historyRef, indexRef) => {
9
+ export const startSpeechToTextFromMic = async (setSpeechToTextArray, // 完整句子
10
+ config, historyRef, indexRef, setPartialTranscript // ✅ 新增:暫存逐字
11
+ ) => {
9
12
  const tokenRes = await getTokenOrRefresh(config.apiKey, config.apiSecret);
10
13
  if (!tokenRes.authToken || !tokenRes.region) {
11
14
  console.error('Speech token retrieval failed:', tokenRes.error);
@@ -13,20 +16,28 @@ export const startSpeechToTextFromMic = async (setSpeechToTextArray, config, his
13
16
  }
14
17
  const speechConfig = SpeechConfig.fromAuthorizationToken(tokenRes.authToken, tokenRes.region);
15
18
  speechConfig.speechRecognitionLanguage = 'en-US';
19
+ // 靜音判斷與 segmentation 設定
16
20
  speechConfig.setProperty(PropertyId.SpeechServiceConnection_InitialSilenceTimeoutMs, '10000');
17
21
  speechConfig.setProperty(PropertyId.SpeechServiceConnection_EndSilenceTimeoutMs, '86400000');
18
22
  speechConfig.setProperty(PropertyId.Speech_SegmentationSilenceTimeoutMs, '1000');
19
23
  const audioConfig = AudioConfig.fromDefaultMicrophoneInput();
20
24
  const recognizer = new SpeechRecognizer(speechConfig, audioConfig);
25
+ // 暫存逐字
21
26
  recognizer.recognizing = (_s, e) => {
22
- historyRef.current[indexRef.current] = e.result.text;
23
- setSpeechToTextArray([...historyRef.current]);
27
+ if (setPartialTranscript) {
28
+ setPartialTranscript(e.result.text);
29
+ }
24
30
  };
31
+ // 完整句子
25
32
  recognizer.recognized = (_s, e) => {
26
33
  if (e.result.reason === ResultReason.RecognizedSpeech) {
27
- historyRef.current[indexRef.current] = e.result.text;
28
- setSpeechToTextArray([...historyRef.current]);
34
+ const text = e.result.text;
35
+ historyRef.current[indexRef.current] = text;
29
36
  indexRef.current += 1;
37
+ // ✅ 關鍵:只把「本次完整句子」回推給 UI
38
+ setSpeechToTextArray([text]);
39
+ if (setPartialTranscript)
40
+ setPartialTranscript('');
30
41
  }
31
42
  };
32
43
  recognizer.canceled = (_s, e) => {
@@ -1,6 +1,7 @@
1
1
  interface Props {
2
2
  apiKey: string;
3
3
  apiSecret: string;
4
+ autoClearTranscript?: boolean;
4
5
  }
5
6
  type UseSpeechToTextFromMicResult = {
6
7
  start: () => Promise<void>;
@@ -8,7 +9,8 @@ type UseSpeechToTextFromMicResult = {
8
9
  clear: () => void;
9
10
  isRecording: boolean;
10
11
  transcript: string;
12
+ partialTranscript: string;
11
13
  };
12
- export declare function useSpeechToTextFromMic({ apiKey, apiSecret }: Props): UseSpeechToTextFromMicResult;
14
+ export declare function useSpeechToTextFromMic({ apiKey, apiSecret, autoClearTranscript, }: Props): UseSpeechToTextFromMicResult;
13
15
  export {};
14
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/lib/useSpeechToTextFromMic/index.ts"],"names":[],"mappings":"AAIA,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,4BAA4B,GAAG;IAClC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,4BAA4B,CAqDjG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/lib/useSpeechToTextFromMic/index.ts"],"names":[],"mappings":"AAIA,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,KAAK,4BAA4B,GAAG;IAClC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EACrC,MAAM,EACN,SAAS,EACT,mBAA0B,GAC3B,EAAE,KAAK,GAAG,4BAA4B,CAuEtC"}
@@ -1,8 +1,9 @@
1
- import { useRef, useState } from 'react';
1
+ import { useEffect, useRef, useState } from 'react';
2
2
  import { startSpeechToTextFromMic, stopRecognition } from './helper';
3
- export function useSpeechToTextFromMic({ apiKey, apiSecret }) {
3
+ export function useSpeechToTextFromMic({ apiKey, apiSecret, autoClearTranscript = true, }) {
4
4
  const [isRecording, setIsRecording] = useState(false);
5
5
  const [transcriptArray, setTranscriptArray] = useState([]);
6
+ const [partialTranscript, setPartialTranscript] = useState('');
6
7
  const [recognizer, setRecognizer] = useState();
7
8
  const wakelock = useRef();
8
9
  const historyRef = useRef([]);
@@ -25,7 +26,7 @@ export function useSpeechToTextFromMic({ apiKey, apiSecret }) {
25
26
  clear();
26
27
  await lockWakeState();
27
28
  setIsRecording(true);
28
- const recognizerInstance = await startSpeechToTextFromMic(setTranscriptArray, { apiKey, apiSecret }, historyRef, indexRef);
29
+ const recognizerInstance = await startSpeechToTextFromMic(setTranscriptArray, { apiKey, apiSecret }, historyRef, indexRef, setPartialTranscript);
29
30
  setRecognizer(recognizerInstance);
30
31
  };
31
32
  const stop = () => {
@@ -38,7 +39,16 @@ export function useSpeechToTextFromMic({ apiKey, apiSecret }) {
38
39
  historyRef.current = [];
39
40
  indexRef.current = 0;
40
41
  setTranscriptArray([]);
42
+ setPartialTranscript('');
41
43
  };
44
+ useEffect(() => {
45
+ if (autoClearTranscript && transcriptArray.length > 0) {
46
+ const timer = setTimeout(() => {
47
+ setTranscriptArray([]);
48
+ }, 100);
49
+ return () => clearTimeout(timer);
50
+ }
51
+ }, [transcriptArray, autoClearTranscript]);
42
52
  const transcript = transcriptArray.join(' ');
43
53
  return {
44
54
  start,
@@ -46,5 +56,6 @@ export function useSpeechToTextFromMic({ apiKey, apiSecret }) {
46
56
  clear,
47
57
  isRecording,
48
58
  transcript,
59
+ partialTranscript,
49
60
  };
50
61
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytexbyte/nxtlinq-ai-agent-sdk",
3
- "version": "1.6.8",
3
+ "version": "1.6.9",
4
4
  "description": "Nxtlinq AI Agent SDK - Proprietary Software with enhanced async operation handling",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -59,4 +59,4 @@
59
59
  "universal-cookie": "^8.0.1",
60
60
  "uuid": "^11.1.0"
61
61
  }
62
- }
62
+ }
@@ -1,5 +0,0 @@
1
- /**
2
- * Tests for URL utility functions
3
- */
4
- export {};
5
- //# sourceMappingURL=urlUtils.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"urlUtils.test.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/__tests__/urlUtils.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -1,57 +0,0 @@
1
- /**
2
- * Tests for URL utility functions
3
- */
4
- import { containsUrls, convertUrlsToLinks, convertUrlsToHtml } from '../urlUtils';
5
- describe('URL Utils', () => {
6
- describe('containsUrls', () => {
7
- it('should detect URLs with http protocol', () => {
8
- expect(containsUrls('Visit https://example.com for more info')).toBe(true);
9
- expect(containsUrls('Check out http://test.org')).toBe(true);
10
- });
11
- it('should detect URLs with www', () => {
12
- expect(containsUrls('Go to www.google.com')).toBe(true);
13
- expect(containsUrls('Visit www.example.org')).toBe(true);
14
- });
15
- it('should detect domain names', () => {
16
- expect(containsUrls('Contact us at support@company.com')).toBe(false);
17
- expect(containsUrls('Visit company.com for details')).toBe(true);
18
- });
19
- it('should return false for text without URLs', () => {
20
- expect(containsUrls('This is just plain text')).toBe(false);
21
- expect(containsUrls('No URLs here')).toBe(false);
22
- });
23
- });
24
- describe('convertUrlsToHtml', () => {
25
- it('should convert URLs to HTML anchor tags', () => {
26
- const text = 'Visit https://example.com for more info';
27
- const result = convertUrlsToHtml(text);
28
- expect(result).toContain('<a href="https://example.com"');
29
- expect(result).toContain('target="_blank"');
30
- expect(result).toContain('rel="noopener noreferrer"');
31
- });
32
- it('should handle www URLs', () => {
33
- const text = 'Go to www.google.com';
34
- const result = convertUrlsToHtml(text);
35
- expect(result).toContain('<a href="https://www.google.com"');
36
- });
37
- it('should handle multiple URLs', () => {
38
- const text = 'Visit https://example.com and www.google.com';
39
- const result = convertUrlsToHtml(text);
40
- expect(result).toContain('https://example.com');
41
- expect(result).toContain('https://www.google.com');
42
- });
43
- });
44
- describe('convertUrlsToLinks', () => {
45
- it('should return array with mixed content', () => {
46
- const text = 'Visit https://example.com for more info';
47
- const result = convertUrlsToLinks(text);
48
- expect(Array.isArray(result)).toBe(true);
49
- expect(result.length).toBeGreaterThan(0);
50
- });
51
- it('should handle text without URLs', () => {
52
- const text = 'This is just plain text';
53
- const result = convertUrlsToLinks(text);
54
- expect(result).toEqual([text]);
55
- });
56
- });
57
- });
@@ -1,8 +0,0 @@
1
- /**
2
- * BerifyMe React Instance Fix
3
- *
4
- * This utility ensures that BerifyMe SDK uses the same React instance
5
- * as our SDK, preventing the __SECRET_INTERNALS error.
6
- */
7
- export declare function fixBerifyMeReactInstance(): void;
8
- //# sourceMappingURL=berifyMeReactFix.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"berifyMeReactFix.d.ts","sourceRoot":"","sources":["../../../src/core/utils/berifyMeReactFix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,wBAAwB,IAAI,IAAI,CA4E/C"}
@@ -1,81 +0,0 @@
1
- /**
2
- * BerifyMe React Instance Fix
3
- *
4
- * This utility ensures that BerifyMe SDK uses the same React instance
5
- * as our SDK, preventing the __SECRET_INTERNALS error.
6
- */
7
- export function fixBerifyMeReactInstance() {
8
- try {
9
- // Wait for BerifyMe SDK to load
10
- const checkBerifyMe = () => {
11
- if (window.BerifyMeSDK) {
12
- console.log('[BerifyMe React Fix] BerifyMe SDK detected, applying React instance fix...');
13
- // Method 1: Try to set React instance if the method exists
14
- if (window.BerifyMeSDK.setReactInstance) {
15
- try {
16
- const React = require('react');
17
- const createRoot = require('react-dom/client').createRoot;
18
- window.BerifyMeSDK.setReactInstance(React, createRoot);
19
- console.log('[BerifyMe React Fix] ✅ React instance set successfully');
20
- return;
21
- }
22
- catch (e) {
23
- console.warn('[BerifyMe React Fix] Failed to set React instance via setReactInstance:', e);
24
- }
25
- }
26
- // Method 2: Monkey patch React globals
27
- try {
28
- const React = require('react');
29
- const ReactDOM = require('react-dom');
30
- const createRoot = require('react-dom/client').createRoot;
31
- // Store original globals
32
- const originalReact = window.React;
33
- const originalReactDOM = window.ReactDOM;
34
- // Set our React instance as global
35
- window.React = React;
36
- window.ReactDOM = ReactDOM;
37
- window.ReactDOMClient = { createRoot };
38
- console.log('[BerifyMe React Fix] ✅ React globals patched successfully');
39
- // Restore original globals after a delay
40
- setTimeout(() => {
41
- if (originalReact)
42
- window.React = originalReact;
43
- if (originalReactDOM)
44
- window.ReactDOM = originalReactDOM;
45
- console.log('[BerifyMe React Fix] Original React globals restored');
46
- }, 1000);
47
- }
48
- catch (e) {
49
- console.warn('[BerifyMe React Fix] Failed to patch React globals:', e);
50
- }
51
- // Method 3: Try to patch the BerifyMe modal component
52
- try {
53
- if (window.BerifyMeSDK.modal) {
54
- const originalModal = window.BerifyMeSDK.modal;
55
- const React = require('react');
56
- // Create a wrapper that uses our React instance
57
- window.BerifyMeSDK.modal = (props) => {
58
- return React.createElement(originalModal, props);
59
- };
60
- console.log('[BerifyMe React Fix] ✅ BerifyMe modal component patched');
61
- }
62
- }
63
- catch (e) {
64
- console.warn('[BerifyMe React Fix] Failed to patch BerifyMe modal:', e);
65
- }
66
- }
67
- else {
68
- // Retry after a short delay
69
- setTimeout(checkBerifyMe, 100);
70
- }
71
- };
72
- checkBerifyMe();
73
- }
74
- catch (error) {
75
- console.error('[BerifyMe React Fix] Error applying React instance fix:', error);
76
- }
77
- }
78
- // Auto-apply the fix when this module is loaded
79
- if (typeof window !== 'undefined') {
80
- fixBerifyMeReactInstance();
81
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * React Instance Check Utility
3
- *
4
- * This utility helps prevent React version conflicts by ensuring
5
- * the SDK uses the same React instance as the host application.
6
- */
7
- export declare function checkReactInstance(): void;
8
- export declare function ensureReactCompatibility(): void;
9
- //# sourceMappingURL=reactInstanceCheck.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactInstanceCheck.d.ts","sourceRoot":"","sources":["../../../src/core/utils/reactInstanceCheck.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wBAAgB,kBAAkB,IAAI,IAAI,CAoCzC;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CAG/C"}
@@ -1,46 +0,0 @@
1
- /**
2
- * React Instance Check Utility
3
- *
4
- * This utility helps prevent React version conflicts by ensuring
5
- * the SDK uses the same React instance as the host application.
6
- */
7
- let reactInstanceCheckPerformed = false;
8
- export function checkReactInstance() {
9
- if (reactInstanceCheckPerformed) {
10
- return;
11
- }
12
- try {
13
- // Check if React is available globally
14
- const globalReact = window.React;
15
- const globalReactDOM = window.ReactDOM;
16
- if (globalReact && globalReactDOM) {
17
- console.log('[NxtlinqAIAgent] Using global React instance from host application');
18
- return;
19
- }
20
- // Check if we're in a module environment
21
- if (typeof require !== 'undefined') {
22
- try {
23
- const react = require('react');
24
- const reactDOM = require('react-dom');
25
- if (react && reactDOM) {
26
- console.log('[NxtlinqAIAgent] Using React instance from module system');
27
- return;
28
- }
29
- }
30
- catch (e) {
31
- // Module system not available or React not found
32
- }
33
- }
34
- console.warn('[NxtlinqAIAgent] React instance check completed - using bundled React');
35
- }
36
- catch (error) {
37
- console.error('[NxtlinqAIAgent] React instance check failed:', error);
38
- }
39
- finally {
40
- reactInstanceCheckPerformed = true;
41
- }
42
- }
43
- export function ensureReactCompatibility() {
44
- // This function can be extended to perform more compatibility checks
45
- checkReactInstance();
46
- }
@@ -1,2 +0,0 @@
1
- import '@testing-library/jest-dom';
2
- //# sourceMappingURL=setupTests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setupTests.d.ts","sourceRoot":"","sources":["../src/setupTests.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1,16 +0,0 @@
1
- // Test setup file for Jest
2
- import '@testing-library/jest-dom';
3
- // Mock window.open for URL tests
4
- Object.defineProperty(window, 'open', {
5
- writable: true,
6
- value: jest.fn(),
7
- });
8
- // Mock console methods to avoid noise in tests
9
- global.console = {
10
- ...console,
11
- log: jest.fn(),
12
- debug: jest.fn(),
13
- info: jest.fn(),
14
- warn: jest.fn(),
15
- error: jest.fn(),
16
- };