@elevenlabs/react-native 0.5.12 → 1.0.0-rc.0

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.
Files changed (62) hide show
  1. package/.turbo/turbo-build.log +2 -12
  2. package/.turbo/turbo-check-types.log +1 -1
  3. package/.turbo/turbo-generate-version.log +1 -1
  4. package/.turbo/turbo-lint$colon$es.log +2 -2
  5. package/.turbo/turbo-lint$colon$prettier.log +1 -1
  6. package/CHANGELOG.md +88 -4
  7. package/README.md +42 -324
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +7 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/index.react-native.d.ts +2 -0
  13. package/dist/index.react-native.d.ts.map +1 -0
  14. package/dist/index.react-native.js +35 -0
  15. package/dist/index.react-native.js.map +1 -0
  16. package/dist/version.d.ts +2 -1
  17. package/dist/version.d.ts.map +1 -0
  18. package/dist/version.js +3 -0
  19. package/dist/version.js.map +1 -0
  20. package/package.json +13 -26
  21. package/src/index.react-native.ts +51 -0
  22. package/src/index.ts +25 -16
  23. package/src/version.ts +1 -1
  24. package/tsconfig.build.json +19 -0
  25. package/tsconfig.build.tsbuildinfo +1 -0
  26. package/tsconfig.json +5 -17
  27. package/dist/ElevenLabsProvider.d.ts +0 -30
  28. package/dist/ElevenLabsProvider.test.d.ts +0 -1
  29. package/dist/components/LiveKitRoomWrapper.d.ts +0 -23
  30. package/dist/components/MessageHandler.d.ts +0 -14
  31. package/dist/hooks/useConversationCallbacks.d.ts +0 -5
  32. package/dist/hooks/useConversationSession.d.ts +0 -33
  33. package/dist/hooks/useLiveKitRoom.d.ts +0 -12
  34. package/dist/hooks/useMessageSending.d.ts +0 -7
  35. package/dist/lib.js +0 -2
  36. package/dist/lib.js.map +0 -1
  37. package/dist/lib.modern.js +0 -2
  38. package/dist/lib.modern.js.map +0 -1
  39. package/dist/lib.module.js +0 -2
  40. package/dist/lib.module.js.map +0 -1
  41. package/dist/lib.umd.js +0 -2
  42. package/dist/lib.umd.js.map +0 -1
  43. package/dist/types.d.ts +0 -111
  44. package/dist/utils/constants.d.ts +0 -1
  45. package/dist/utils/overrides.d.ts +0 -2
  46. package/dist/utils/text-only.d.ts +0 -2
  47. package/dist/utils/tokenUtils.d.ts +0 -2
  48. package/jest.config.cjs +0 -263
  49. package/jest.rn-mock.js +0 -15
  50. package/src/ElevenLabsProvider.test.tsx +0 -257
  51. package/src/ElevenLabsProvider.tsx +0 -365
  52. package/src/components/LiveKitRoomWrapper.tsx +0 -94
  53. package/src/components/MessageHandler.tsx +0 -237
  54. package/src/hooks/useConversationCallbacks.ts +0 -15
  55. package/src/hooks/useConversationSession.ts +0 -130
  56. package/src/hooks/useLiveKitRoom.ts +0 -100
  57. package/src/hooks/useMessageSending.ts +0 -33
  58. package/src/types.ts +0 -170
  59. package/src/utils/constants.ts +0 -1
  60. package/src/utils/overrides.ts +0 -48
  61. package/src/utils/text-only.ts +0 -22
  62. package/src/utils/tokenUtils.ts +0 -52
package/jest.config.cjs DELETED
@@ -1,263 +0,0 @@
1
- module.exports = {
2
- // Use React Native preset optimized for TypeScript
3
- preset: 'ts-jest',
4
-
5
- // Use node environment with React Native globals
6
- testEnvironment: 'node',
7
-
8
- // Define test roots
9
- roots: ['<rootDir>/src'],
10
-
11
- // Enhanced test file matching patterns
12
- testMatch: [
13
- '**/__tests__/**/*.(test|spec).+(ts|tsx|js|jsx)',
14
- '**/*.(test|spec).+(ts|tsx|js|jsx)',
15
- '!**/*.d.ts',
16
- '!**/node_modules/**',
17
- ],
18
-
19
- // TypeScript and JavaScript transformation
20
- transform: {
21
- '^.+\\.(ts|tsx)$': ['ts-jest', {
22
- useESM: false,
23
- tsconfig: {
24
- target: 'ES2020',
25
- module: 'commonjs',
26
- moduleResolution: 'node',
27
- allowJs: true,
28
- allowSyntheticDefaultImports: true,
29
- esModuleInterop: true,
30
- skipLibCheck: true,
31
- strict: false, // Relaxed for testing
32
- resolveJsonModule: true,
33
- isolatedModules: true,
34
- },
35
- }],
36
- '^.+\\.(js|jsx)$': 'babel-jest',
37
- },
38
-
39
- // File extensions to handle
40
- moduleFileExtensions: [
41
- 'ts',
42
- 'tsx',
43
- 'js',
44
- 'jsx',
45
- 'json',
46
- 'node',
47
- 'ios.ts',
48
- 'ios.tsx',
49
- 'android.ts',
50
- 'android.tsx',
51
- 'native.ts',
52
- 'native.tsx',
53
- ],
54
-
55
- // Minimal module mapping for React Native modules
56
- moduleNameMapper: {
57
- '^react-native$': '<rootDir>/jest.rn-mock.js',
58
- '^react-native/(.*)$': '<rootDir>/jest.rn-mock.js',
59
- },
60
-
61
- // Setup files
62
- setupFiles: [],
63
-
64
- // Setup files after environment is set up
65
- setupFilesAfterEnv: [],
66
-
67
- // Coverage configuration
68
- collectCoverage: false, // Enable manually with --coverage
69
- collectCoverageFrom: [
70
- 'src/**/*.{ts,tsx}',
71
- '!src/**/*.d.ts',
72
- '!src/**/*.test.{ts,tsx}',
73
- '!src/**/*.spec.{ts,tsx}',
74
- '!src/**/test-*.{ts,tsx}',
75
- '!src/**/__tests__/**',
76
- '!src/**/__mocks__/**',
77
- '!**/node_modules/**',
78
- ],
79
-
80
- // Coverage thresholds
81
- coverageThreshold: {
82
- global: {
83
- branches: 80,
84
- functions: 80,
85
- lines: 80,
86
- statements: 80,
87
- },
88
- // Per-file thresholds for critical files
89
- './src/conversation.ts': {
90
- branches: 90,
91
- functions: 90,
92
- lines: 90,
93
- statements: 90,
94
- },
95
- './src/errors.ts': {
96
- branches: 95,
97
- functions: 95,
98
- lines: 95,
99
- statements: 95,
100
- },
101
- },
102
-
103
- // Coverage reporters
104
- coverageReporters: [
105
- 'text',
106
- 'text-summary',
107
- 'lcov',
108
- 'html',
109
- 'json',
110
- ],
111
-
112
- // Coverage directory
113
- coverageDirectory: '<rootDir>/coverage',
114
-
115
- // Ignore patterns for coverage
116
- coveragePathIgnorePatterns: [
117
- '/node_modules/',
118
- '/dist/',
119
- '/build/',
120
- '/.next/',
121
- '/coverage/',
122
- '\\.d\\.ts$',
123
- '\\.test\\.ts$',
124
- '\\.spec\\.ts$',
125
- ],
126
-
127
- // Test timeout (increased for React Native)
128
- testTimeout: 15000,
129
-
130
- // Clear mocks after each test
131
- clearMocks: true,
132
-
133
- // Restore mocks after each test
134
- restoreMocks: true,
135
-
136
- // Reset modules before each test
137
- resetModules: false, // Keep false for performance
138
-
139
- // Verbose output
140
- verbose: false, // Set to true for debugging
141
-
142
- // Error handling
143
- errorOnDeprecated: true,
144
-
145
- // Performance optimizations
146
- maxWorkers: '50%', // Use half the available CPU cores
147
-
148
- // Cache configuration
149
- cache: true,
150
- cacheDirectory: '<rootDir>/node_modules/.cache/jest',
151
-
152
- // Watch mode configuration
153
- watchPathIgnorePatterns: [
154
- '/node_modules/',
155
- '/dist/',
156
- '/build/',
157
- '/coverage/',
158
- '\\.git/',
159
- ],
160
-
161
- // Test result processing
162
- testResultsProcessor: undefined,
163
-
164
- // Custom environment variables for React Native
165
- testEnvironmentOptions: {
166
- url: 'http://localhost',
167
- },
168
-
169
- // Resolver configuration for React Native modules
170
- resolver: undefined, // Use default resolver with moduleNameMapping
171
-
172
- // Transform ignore patterns (important for React Native)
173
- transformIgnorePatterns: [
174
- 'node_modules/(?!(react-native|@react-native|@livekit|livekit-client)/)',
175
- ],
176
-
177
- // Module directories
178
- moduleDirectories: [
179
- 'node_modules',
180
- '<rootDir>/src',
181
- ],
182
-
183
- // Global setup and teardown
184
- globalSetup: undefined,
185
- globalTeardown: undefined,
186
-
187
- // Custom reporters
188
- reporters: [
189
- 'default',
190
- // Add custom reporters here if needed
191
- // ['jest-junit', { outputDirectory: 'test-results', outputName: 'junit.xml' }],
192
- ],
193
-
194
- // Snapshot configuration
195
- snapshotSerializers: [],
196
-
197
- // Test path ignore patterns
198
- testPathIgnorePatterns: [
199
- '/node_modules/',
200
- '/dist/',
201
- '/build/',
202
- '/coverage/',
203
- ],
204
-
205
- // Silent mode
206
- silent: false,
207
-
208
- // Notify configuration
209
- notify: false,
210
- notifyMode: 'failure-change',
211
-
212
- // Force exit
213
- forceExit: false,
214
-
215
- // Detect open handles
216
- detectOpenHandles: false, // Set to true for debugging
217
-
218
- // Detect leaked handles
219
- detectLeaks: false, // Set to true for debugging
220
-
221
- // Bail configuration
222
- bail: 0, // Run all tests
223
-
224
- // Collect coverage from untested files
225
- // collectCoverageOnlyFrom removed - replaced by collectCoverageFrom
226
-
227
- // Coverage provider
228
- coverageProvider: 'v8', // Faster than babel
229
-
230
- // Extensions to ignore
231
- modulePathIgnorePatterns: [
232
- '<rootDir>/dist/',
233
- '<rootDir>/build/',
234
- ],
235
-
236
- // Project configuration for monorepo support
237
- projects: undefined,
238
-
239
- // Runner configuration
240
- runner: 'jest-runner',
241
-
242
- // Test name pattern
243
- testNamePattern: undefined,
244
-
245
- // Only changed files
246
- onlyChanged: false,
247
-
248
- // Pass with no tests
249
- passWithNoTests: true,
250
-
251
- // Use stderr
252
- useStderr: false,
253
-
254
- // Watch plugins
255
- watchPlugins: [
256
- // Removed jest-watch-typeahead plugins - not installed
257
- ],
258
-
259
- // Timezone
260
- fakeTimers: {
261
- enableGlobally: false // Use real timers by default
262
- },
263
- };
package/jest.rn-mock.js DELETED
@@ -1,15 +0,0 @@
1
- // Simple React Native mock for Jest
2
- module.exports = {
3
- Platform: {
4
- OS: 'ios',
5
- select: jest.fn((options) => options.ios),
6
- },
7
- StyleSheet: {
8
- create: jest.fn((styles) => styles),
9
- flatten: jest.fn((styles) => styles),
10
- },
11
- Dimensions: {
12
- get: jest.fn(() => ({ width: 375, height: 667 })),
13
- },
14
- // Add any other React Native modules as needed
15
- };
@@ -1,257 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react-native';
3
- import { ElevenLabsProvider, useConversation } from './ElevenLabsProvider';
4
- import type { ReactNode } from 'react';
5
-
6
- // Suppress react-test-renderer deprecation warnings during tests
7
- const originalWarn = console.warn;
8
- const originalError = console.error;
9
-
10
- beforeAll(() => {
11
- console.warn = (...args) => {
12
- if (args[0]?.includes?.('react-test-renderer is deprecated')) return;
13
- originalWarn(...args);
14
- };
15
- console.error = (...args) => {
16
- if (args[0]?.includes?.('react-test-renderer is deprecated')) return;
17
- originalError(...args);
18
- };
19
- });
20
-
21
- afterAll(() => {
22
- console.warn = originalWarn;
23
- console.error = originalError;
24
- });
25
-
26
- // Simple test component to avoid React Native import issues
27
- const TestText = ({ children }: { children: ReactNode }) => (
28
- <div>{children}</div>
29
- );
30
-
31
- // Mock LiveKit
32
- jest.mock('@livekit/react-native', () => ({
33
- registerGlobals: jest.fn(),
34
- }));
35
-
36
- // Mock hooks with inline functions to avoid hoisting issues
37
- jest.mock('./hooks/useConversationSession', () => ({
38
- useConversationSession: () => ({
39
- startSession: jest.fn(),
40
- endSession: jest.fn(),
41
- overrides: {},
42
- customLlmExtraBody: undefined,
43
- defaultServerUrl: 'https://api.elevenlabs.io/v1/convai',
44
- }),
45
- }));
46
-
47
- jest.mock('./hooks/useConversationCallbacks', () => ({
48
- useConversationCallbacks: () => ({
49
- callbacksRef: { current: {} },
50
- setCallbacks: jest.fn(),
51
- }),
52
- }));
53
-
54
- jest.mock('./hooks/useLiveKitRoom', () => ({
55
- useLiveKitRoom: () => ({
56
- room: null,
57
- localParticipant: null,
58
- roomConnected: false,
59
- handleParticipantReady: jest.fn(),
60
- handleConnected: jest.fn(),
61
- handleDisconnected: jest.fn(),
62
- handleError: jest.fn(),
63
- }),
64
- }));
65
-
66
- jest.mock('./hooks/useMessageSending', () => ({
67
- useMessageSending: () => ({
68
- sendMessage: jest.fn(),
69
- sendFeedback: jest.fn(),
70
- sendContextualUpdate: jest.fn(),
71
- sendUserMessage: jest.fn(),
72
- sendUserActivity: jest.fn(),
73
- }),
74
- }));
75
-
76
- jest.mock('./components/MessageHandler', () => ({
77
- MessageHandler: () => null,
78
- }));
79
-
80
- jest.mock('./components/LiveKitRoomWrapper', () => ({
81
- LiveKitRoomWrapper: ({ children }: { children: ReactNode }) => (
82
- // The actual LiveKitRoomWrapper receives key prop from parent (ElevenLabsProvider)
83
- // Children are passed through and should not remount when key changes
84
- <div>{children}</div>
85
- ),
86
- }));
87
-
88
- describe('ElevenLabsProvider', () => {
89
- describe('Core Functionality', () => {
90
- it('should throw error when useConversation is used outside provider', () => {
91
- const BadComponent = () => {
92
- useConversation();
93
- return <TestText>Should not render</TestText>;
94
- };
95
-
96
- const originalError = console.error;
97
- console.error = jest.fn();
98
-
99
- expect(() => {
100
- render(<BadComponent />);
101
- }).toThrow('useConversation must be used within ElevenLabsProvider');
102
-
103
- console.error = originalError;
104
- });
105
-
106
- it('should provide conversation context and all methods when used within provider', () => {
107
- const TestComponent = () => {
108
- const conversation = useConversation();
109
-
110
- // Verify all methods exist and are functions
111
- expect(typeof conversation.startSession).toBe('function');
112
- expect(typeof conversation.endSession).toBe('function');
113
- expect(typeof conversation.sendFeedback).toBe('function');
114
- expect(typeof conversation.sendContextualUpdate).toBe('function');
115
- expect(typeof conversation.sendUserMessage).toBe('function');
116
- expect(typeof conversation.sendUserActivity).toBe('function');
117
-
118
- // Verify all properties exist with correct types
119
- expect(typeof conversation.status).toBe('string');
120
- expect(typeof conversation.isSpeaking).toBe('boolean');
121
- expect(typeof conversation.canSendFeedback).toBe('boolean');
122
-
123
- return <TestText>Test passed</TestText>;
124
- };
125
-
126
- expect(() => {
127
- render(
128
- <ElevenLabsProvider>
129
- <TestComponent />
130
- </ElevenLabsProvider>
131
- );
132
- }).not.toThrow();
133
- });
134
-
135
- it('should allow methods to be called without throwing errors', () => {
136
- const TestComponent = () => {
137
- const conversation = useConversation();
138
-
139
- // Suppress console.warn for sendFeedback test since canSendFeedback is false by default
140
- const originalWarn = console.warn;
141
- console.warn = jest.fn();
142
-
143
- // Test that all methods can be called safely
144
- expect(() => conversation.startSession({ agentId: 'test' })).not.toThrow();
145
- expect(() => conversation.endSession()).not.toThrow();
146
- expect(() => conversation.sendFeedback(true)).not.toThrow();
147
- expect(() => conversation.sendContextualUpdate('test context')).not.toThrow();
148
- expect(() => conversation.sendUserMessage('test message')).not.toThrow();
149
- expect(() => conversation.sendUserActivity()).not.toThrow();
150
-
151
- // Restore console.warn
152
- console.warn = originalWarn;
153
-
154
- return <TestText>Method tests passed</TestText>;
155
- };
156
-
157
- expect(() => {
158
- render(
159
- <ElevenLabsProvider>
160
- <TestComponent />
161
- </ElevenLabsProvider>
162
- );
163
- }).not.toThrow();
164
- });
165
-
166
- it('should render children components successfully', () => {
167
- // Simple test - if rendering doesn't throw, children are successfully rendered
168
- expect(() => {
169
- render(
170
- <ElevenLabsProvider>
171
- <TestText>Child component rendered</TestText>
172
- </ElevenLabsProvider>
173
- );
174
- }).not.toThrow();
175
- });
176
-
177
- it('should provide conversation context with options', () => {
178
- const TestComponent = () => {
179
- const conversation = useConversation({
180
- onConnect: jest.fn(),
181
- onDisconnect: jest.fn(),
182
- onError: jest.fn(),
183
- });
184
-
185
- expect(conversation).toBeDefined();
186
- return <TestText>Options test passed</TestText>;
187
- };
188
-
189
- expect(() => {
190
- render(
191
- <ElevenLabsProvider>
192
- <TestComponent />
193
- </ElevenLabsProvider>
194
- );
195
- }).not.toThrow();
196
- });
197
-
198
- it('should maintain stable conversation object reference to prevent infinite loops', () => {
199
- const useEffectCallCount = jest.fn();
200
- const conversationRefs: any[] = [];
201
- let capturedConversation: any = null;
202
-
203
- const TestComponent = () => {
204
- const conversation = useConversation();
205
-
206
- // Capture conversation for external testing
207
- capturedConversation = conversation;
208
-
209
- // Track the conversation object reference on each render
210
- conversationRefs.push(conversation);
211
-
212
- // Using conversation in useEffect deps should not cause an infinite loop
213
- React.useEffect(() => {
214
- useEffectCallCount();
215
- // Simulate calling startSession which triggers state changes
216
- // In real usage, this would call conversation.startSession(...)
217
- }, [conversation]);
218
-
219
- return <TestText>Test component</TestText>;
220
- };
221
-
222
- const { rerender } = render(
223
- <ElevenLabsProvider>
224
- <TestComponent />
225
- </ElevenLabsProvider>
226
- );
227
-
228
- // Initial render - effect should run once
229
- expect(useEffectCallCount).toHaveBeenCalledTimes(1);
230
- const firstConversationRef = conversationRefs[0];
231
-
232
- // Verify the conversation object has all required properties
233
- expect(firstConversationRef).toHaveProperty('startSession');
234
- expect(firstConversationRef).toHaveProperty('endSession');
235
- expect(firstConversationRef).toHaveProperty('status');
236
- expect(firstConversationRef).toHaveProperty('isSpeaking');
237
-
238
- // Force a re-render by calling rerender
239
- rerender(
240
- <ElevenLabsProvider>
241
- <TestComponent />
242
- </ElevenLabsProvider>
243
- );
244
-
245
- // After re-render, verify conversation reference is still the same
246
- expect(conversationRefs[conversationRefs.length - 1]).toBe(firstConversationRef);
247
-
248
- // Effect should NOT run again because conversation reference is stable
249
- expect(useEffectCallCount).toHaveBeenCalledTimes(1);
250
-
251
- // Verify ALL conversation references collected are the same object
252
- conversationRefs.forEach((ref, index) => {
253
- expect(ref).toBe(firstConversationRef);
254
- });
255
- });
256
- });
257
- });