interview-widget 0.0.7 → 0.0.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.
Files changed (33) hide show
  1. package/README.md +197 -101
  2. package/dist/components/interview/interview-controller.d.ts +8 -0
  3. package/dist/components/interview/interview-header.d.ts +1 -0
  4. package/dist/components/interview/question-display.d.ts +3 -2
  5. package/dist/components/modals/exit-confirmation-modal.d.ts +7 -0
  6. package/dist/components/timer/timer-display.d.ts +13 -0
  7. package/dist/components/ui/dialog.d.ts +13 -0
  8. package/dist/context/interview-widget-context.d.ts +34 -0
  9. package/dist/hooks/use-api.d.ts +26 -0
  10. package/dist/hooks/use-dialog.d.ts +6 -0
  11. package/dist/hooks/use-interview-api.d.ts +5 -0
  12. package/dist/hooks/use-stt.d.ts +20 -0
  13. package/dist/hooks/use-timer.d.ts +12 -0
  14. package/dist/hooks/use-tts.d.ts +15 -0
  15. package/dist/index.d.ts +3 -2
  16. package/dist/services/api/index.d.ts +2 -0
  17. package/dist/services/api/interview-api.d.ts +23 -0
  18. package/dist/services/stt/index.d.ts +1 -0
  19. package/dist/services/stt/stt-service.d.ts +78 -0
  20. package/dist/services/timer/index.d.ts +6 -0
  21. package/dist/services/timer/timer-service.d.ts +81 -0
  22. package/dist/services/tts/index.d.ts +1 -0
  23. package/dist/services/tts/tts-service.d.ts +43 -0
  24. package/dist/types.d.ts +69 -14
  25. package/dist/utils/api-error-classifier.d.ts +2 -0
  26. package/dist/utils/constants.d.ts +3 -0
  27. package/dist/utils/helper.d.ts +6 -0
  28. package/dist/utils/resilient-fetch.d.ts +9 -0
  29. package/dist/widget.css +1 -1
  30. package/dist/widget.es.js +1714 -250
  31. package/dist/widget.umd.js +2 -2
  32. package/package.json +1 -1
  33. /package/dist/components/{onboarding-modal.d.ts → modals/onboarding-modal.d.ts} +0 -0
package/README.md CHANGED
@@ -1,27 +1,70 @@
1
1
  # Interview Widget
2
2
 
3
- A customizable React interview widget that can be easily embedded into any website or React application.
3
+ A modern React interview experience widget with built‑in timer flow, STT (speech‑to‑text), and TTS (text‑to‑speech). It can be embedded via NPM or a CDN and configured through a single provider.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - 📸 **Video capture** with camera integration
8
8
  - 📱 **Responsive design** with mobile support
9
- - 🔧 **Flexible positioning** (inline, fixed bottom-right/left)
10
9
  - 🧩 **TypeScript support** with full type definitions
11
10
  - 🎯 **CDN-ready** for easy integration into any website
12
11
  - 🔄 **Q&A structured interview flow**
13
- - 💬 **Configurable questions** for different interview types
14
- - 🎪 **Tailwind CSS** with prefixed classes to avoid conflicts
15
- - **Smooth animations** and modern UI
12
+ - ⏱️ **Advanced Timer System** with phase management
13
+ - 🔈 **Text-to-Speech integration** for transcribing
14
+ - 🎤 **Speech-to-Text integration** for voice answers
15
+ - 🔄 **Automatic phase transitions** (thinking → answering → editing)
16
+ - ✅ **Time validation** before starting new questions
16
17
 
17
18
  ## Quick Start
18
19
 
19
- ### CDN Integration (Any Website)
20
+ ### 1) Install (React apps)
20
21
 
21
- Add these scripts to your HTML:
22
+ ```bash
23
+ npm install interview-widget
24
+ ```
25
+
26
+ Minimal usage:
27
+
28
+ ```tsx
29
+ import React from "react";
30
+ import { InterviewWidget, InterviewWidgetProvider } from "interview-widget";
31
+ import "interview-widget/style.css";
32
+
33
+ export default function App() {
34
+ return (
35
+ <InterviewWidgetProvider
36
+ config={{
37
+ api: { baseUrl: "/api" },
38
+ interview: {
39
+ stt: {
40
+ provider: "groq",
41
+ model: "whisper-large-v3-turbo",
42
+ language: "en",
43
+ },
44
+ tts: { provider: "piper" },
45
+ timers: {
46
+ thinkingDuration: 30,
47
+ answeringDuration: 120,
48
+ editingDuration: 30,
49
+ },
50
+ },
51
+ }}
52
+ >
53
+ <InterviewWidget
54
+ title="Technical Interview"
55
+ onInterviewEnd={() => {
56
+ console.log("🎉🎉 Interview ended 🎉🎉");
57
+ }}
58
+ />
59
+ </InterviewWidgetProvider>
60
+ );
61
+ }
62
+ ```
63
+
64
+ ### 2) CDN usage (Any website)
22
65
 
23
66
  ```html
24
- <!-- Load React and ReactDOM from CDN -->
67
+ <!-- React 18 UMD -->
25
68
  <script
26
69
  crossorigin
27
70
  src="https://unpkg.com/react@18/umd/react.production.min.js"
@@ -31,123 +74,176 @@ Add these scripts to your HTML:
31
74
  src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"
32
75
  ></script>
33
76
 
34
- <!-- Load the interview widget CSS -->
77
+ <!-- Styles + Widget UMD -->
35
78
  <link
36
79
  rel="stylesheet"
37
80
  href="https://unpkg.com/interview-widget@latest/dist/widget.css"
38
81
  />
39
-
40
- <!-- Load the interview widget JavaScript -->
41
82
  <script src="https://unpkg.com/interview-widget@latest/dist/widget.umd.js"></script>
42
83
 
84
+ <div id="interview-widget-container"></div>
43
85
  <script>
44
86
  document.addEventListener("DOMContentLoaded", function () {
45
- const { InterviewWidget } = window.InterviewWidget;
87
+ const { InterviewWidget, InterviewWidgetProvider } = window.InterviewWidget;
46
88
 
47
- // Define your interview questions
48
- const questions = [
89
+ const app = React.createElement(
90
+ InterviewWidgetProvider,
49
91
  {
50
- id: "1",
51
- text: "Can you please introduce yourself?",
52
- timestamp: new Date(),
92
+ config: {
93
+ api: { baseUrl: "/api" },
94
+ interview: {
95
+ timers: {
96
+ thinkingDuration: 30,
97
+ answeringDuration: 120,
98
+ editingDuration: 30,
99
+ },
100
+ stt: {
101
+ provider: "groq",
102
+ model: "whisper-large-v3-turbo",
103
+ language: "en",
104
+ },
105
+ tts: { provider: "piper" },
106
+ },
107
+ },
53
108
  },
54
- {
55
- id: "2",
56
- text: "What experience do you have with our required technologies?",
57
- timestamp: new Date(),
58
- },
59
- {
60
- id: "3",
61
- text: "What are your strengths and weaknesses?",
62
- timestamp: new Date(),
63
- },
64
- ];
65
-
66
- ReactDOM.render(
67
- React.createElement(InterviewWidget, {
68
- title: "Developer Interview",
69
- questions: questions,
70
- position: "bottom-right",
71
- }),
72
- document.getElementById("interview-widget-container")
109
+ React.createElement(InterviewWidget, { title: "Developer Interview" })
73
110
  );
111
+
112
+ ReactDOM.render(app, document.getElementById("interview-widget-container"));
74
113
  });
75
114
  </script>
76
115
  ```
77
116
 
78
- ### React Application Integration
117
+ ## Public API
79
118
 
80
- ```bash
81
- npm install interview-widget
82
- ```
119
+ ### <InterviewWidget />
83
120
 
84
- ```tsx
85
- import React, { useState } from "react";
86
- import {
87
- InterviewWidget,
88
- InterviewQuestion,
89
- InterviewAnswer,
90
- } from "interview-widget";
91
- import "interview-widget/style.css";
121
+ ### InterviewWidget Props
92
122
 
93
- export function InterviewWidgetDemo() {
94
- const questions: InterviewQuestion[] = [
95
- {
96
- id: "1",
97
- text: "Can you please introduce yourself?",
98
- timestamp: new Date(),
99
- },
100
- {
101
- id: "2",
102
- text: "What experience do you have with our required technologies?",
103
- timestamp: new Date(),
104
- },
105
- ];
106
-
107
- const handleAnswerSubmit = (answer: InterviewAnswer) => {
108
- // Handle submitting answer to your backend
109
- console.log("User answered:", answer);
110
- };
111
-
112
- const handleComplete = (answers: InterviewAnswer[]) => {
113
- // Handle interview completion
114
- console.log("All answers:", answers);
115
- };
123
+ | Prop | Type | Default | Description |
124
+ | ---------------- | ------------ | ------------- | ------------------------------------------------------------ |
125
+ | `interviewId` | `string` | Required | Unique interview identifier used for backend API calls |
126
+ | `title` | `string` | `"Interview"` | Title displayed in the interview header |
127
+ | `onInterviewEnd` | `() => void` | `undefined` | Called when the interview completes or the user exits |
128
+ | `className` | `string` | `""` | Additional CSS classes applied to the outer widget container |
116
129
 
117
- return (
118
- <div>
119
- <InterviewWidget
120
- title="Technical Interview"
121
- questions={questions}
122
- onAnswerSubmit={handleAnswerSubmit}
123
- onComplete={handleComplete}
124
- />
125
- </div>
126
- );
127
- }
130
+ Notes:
131
+
132
+ - Internally uses an InterviewController that orchestrates the full flow using the configured API/STT/TTS/Timer.
133
+ - The interview id is currently derived internally; integrate with your backend by configuring the API base and auth.
134
+
135
+ ### <InterviewWidgetProvider />
136
+
137
+ Wrap your app (or the widget) to provide configuration. See full config reference below.
138
+
139
+ ```tsx
140
+ <InterviewWidgetProvider config={{ api: { baseUrl: "/api" } }}>
141
+ <InterviewWidget />
142
+ </InterviewWidgetProvider>
128
143
  ```
129
144
 
130
- ## API Reference
145
+ ## Configuration reference (Provider)
131
146
 
132
- ### InterviewWidget Props
147
+ Pass this object to `InterviewWidgetProvider` via the `config` prop. Tables list all keys, types, and defaults.
148
+
149
+ ### Top-level
150
+
151
+ | Prop | Type | Default | Description |
152
+ | --------- | ------ | --------- | ---------------------------------------------- |
153
+ | api | object | see below | Backend/API configuration |
154
+ | ui | object | see below | UI customization tokens |
155
+ | interview | object | see below | Interview behavior settings (timers, STT, TTS) |
156
+
157
+ ### api
158
+
159
+ | Prop | Type | Default | Description |
160
+ | ----------- | ------ | --------- | ------------------------------------------------------ |
161
+ | baseUrl | string | "/api" | Base URL for backend endpoints |
162
+ | authToken | string | undefined | Optional bearer token appended as Authorization header |
163
+ | retryConfig | object | see below | Retry policy for fetch calls |
164
+
165
+ retryConfig
166
+
167
+ | Prop | Type | Default | Description |
168
+ | --------- | ------------------------ | ------------- | ------------------------------------------ |
169
+ | attempts | number | 3 | Number of retry attempts |
170
+ | backoff | "fixed" \| "exponential" | "exponential" | Backoff strategy |
171
+ | baseDelay | number (ms) | 1000 | Base delay between retries in milliseconds |
172
+
173
+ ### ui
174
+
175
+ | Prop | Type | Default | Description |
176
+ | ------------ | ------------ | --------- | -------------------------------------- |
177
+ | baseColor | string (hex) | "#3B82F6" | Primary brand color used by the widget |
178
+ | borderRadius | string (CSS) | "8px" | Global corner radius for components |
179
+
180
+ ### interview
181
+
182
+ | Prop | Type | Default | Description |
183
+ | ------ | ------ | --------- | ----------------------------------------- |
184
+ | timers | object | see below | Per-phase and global timing configuration |
185
+ | stt | object | see below | Speech-to-Text provider settings |
186
+ | tts | object | see below | Text-to-Speech provider settings |
187
+
188
+ timers
189
+
190
+ | Prop | Type | Default | Description |
191
+ | -------------------------- | ---------- | ------- | --------------------------------------------------------- |
192
+ | thinkingDuration | number (s) | 30 | Timebox for the Thinking phase |
193
+ | answeringDuration | number (s) | 120 | Timebox for the Answering phase |
194
+ | editingDuration | number (s) | 30 | Timebox for the Editing phase |
195
+ | totalInterviewDuration | number (s) | 600 | Overall interview time cap |
196
+ | minimumTimeForNextQuestion | number (s) | 120 | Minimum time required to allow starting the next question |
197
+
198
+ stt
199
+
200
+ | Prop | Type | Default | Description |
201
+ | -------- | ---------------------------------- | ------------------------ | -------------------------------------- |
202
+ | provider | "groq" \| "deepgram" | "groq" | STT vendor to use |
203
+ | model | "whisper-large-v3-turbo" \| string | "whisper-large-v3-turbo" | STT model identifier |
204
+ | language | "en" | "en" | Language code passed to the STT engine |
205
+
206
+ tts
207
+
208
+ | Prop | Type | Default | Description |
209
+ | -------- | ------- | ------- | ----------------- |
210
+ | provider | "piper" | "piper" | TTS vendor to use |
211
+
212
+ Notes on defaults:
213
+
214
+ - Base defaults come from `src/utils/constants.ts` (`defaultConfig`).
215
+ - `totalInterviewDuration` and `minimumTimeForNextQuestion` default to 600s and 120s respectively via the TimerService if not explicitly provided.
216
+
217
+ ## How it works
218
+
219
+ The widget composes several parts:
220
+
221
+ - TimerService controls phases and timeboxes
222
+ - TTS speaks the question in the Reading phase
223
+ - STT records and transcribes the answer in the Answering/Transcribing phases
224
+ - A resilient API client hits your backend to fetch the next question and submit answers
225
+
226
+ ### Timer phases
227
+
228
+ `idle → fetching_question → reading_question → thinking → answering → transcribing → editing → submitting → completed`
229
+
230
+ You’ll see a Start button, a Next Phase button during active phases, a live countdown, and a completion screen.
231
+
232
+ ## Documentation
233
+
234
+ - Timer system: `docs/timer.md`
235
+ - STT integration: `docs/stt-integration.md`
236
+ - TTS integration: `docs/tts-integration.md`
237
+ - API layer overview: `docs/api-layer.md`
238
+ - Flow simulation and diagrams: `docs/flow-simulation.md`
239
+
240
+ ## Development
241
+
242
+ Local scripts:
133
243
 
134
- | Prop | Type | Default | Description |
135
- | ---------------- | -------------------------------------- | ------------- | --------------------------------------- |
136
- | `title` | `string` | `"Interview"` | Title displayed in the interview header |
137
- | `candidateName` | `string` | `""` | Optional name of the candidate |
138
- | `questions` | `InterviewQuestion[]` | Required | Array of interview questions |
139
- | `onAnswerSubmit` | `(answer: InterviewAnswer) => void` | `undefined` | Callback when user submits an answer |
140
- | `onComplete` | `(answers: InterviewAnswer[]) => void` | `undefined` | Callback when interview is completed |
141
- | `className` | `string` | `""` | Additional CSS classes |
142
- | `height` | `string` | `"600px"` | Height of the interview widget |
143
- | `width` | `string` | `"100%"` | Width of the interview widget |
144
-
145
- ## Browser Support
146
-
147
- - Chrome (latest)
148
- - Firefox (latest)
149
- - Safari (latest)
150
- - Edge (latest)
244
+ - `npm run dev` – Start Vite dev server
245
+ - `npm run build` Type-check and build library bundles (UMD/ESM)
246
+ - `npm run preview` Preview the production build
151
247
 
152
248
  ## Contributing
153
249
 
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+ interface InterviewControllerProps {
3
+ interviewId: string;
4
+ onComplete?: () => void;
5
+ className?: string;
6
+ }
7
+ declare const InterviewController: React.FC<InterviewControllerProps>;
8
+ export default InterviewController;
@@ -1,6 +1,7 @@
1
1
  import { default as React } from 'react';
2
2
  interface InterviewHeaderProps {
3
3
  title: string;
4
+ onExit: () => void;
4
5
  }
5
6
  declare const InterviewHeader: React.FC<InterviewHeaderProps>;
6
7
  export default InterviewHeader;
@@ -1,7 +1,8 @@
1
1
  import { default as React } from 'react';
2
- import { InterviewQuestion } from '../../types';
2
+ import { InterviewQuestionData } from '../../types';
3
3
  interface QuestionDisplayProps {
4
- question: InterviewQuestion;
4
+ question: InterviewQuestionData | null;
5
+ isLoading?: boolean;
5
6
  }
6
7
  declare const QuestionDisplay: React.FC<QuestionDisplayProps>;
7
8
  export default QuestionDisplay;
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ confirmExitInterview: () => void;
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ }
6
+ export declare const ExitConfirmationModal: ({ confirmExitInterview, isOpen, onClose, }: Props) => import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { TimerState } from '../../services/timer/timer-service';
3
+ interface TimerDisplayProps {
4
+ state: TimerState;
5
+ className?: string;
6
+ defaultTimers?: {
7
+ thinking?: number;
8
+ answering?: number;
9
+ editing?: number;
10
+ };
11
+ }
12
+ declare const TimerDisplay: React.FC<TimerDisplayProps>;
13
+ export default TimerDisplay;
@@ -0,0 +1,13 @@
1
+ import { default as React, ReactNode } from 'react';
2
+ interface DialogProps {
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ children: ReactNode;
6
+ title?: string;
7
+ showCloseButton?: boolean;
8
+ closeOnOverlayClick?: boolean;
9
+ closeOnEscape?: boolean;
10
+ className?: string;
11
+ }
12
+ declare const Dialog: React.FC<DialogProps>;
13
+ export default Dialog;
@@ -0,0 +1,34 @@
1
+ import { ReactNode } from 'react';
2
+ import { InterviewWidgetConfig } from '../types';
3
+ interface InterviewWidgetProviderProps {
4
+ config?: InterviewWidgetConfig;
5
+ children: ReactNode;
6
+ }
7
+ export declare function InterviewWidgetProvider({ config, children, }: InterviewWidgetProviderProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function useInterviewConfig(): InterviewWidgetConfig;
9
+ /**
10
+ * Hook to access specific config sections
11
+ */
12
+ export declare function useAPIConfig(): {
13
+ baseUrl?: string;
14
+ authToken?: string;
15
+ retryConfig?: {
16
+ attempts?: number;
17
+ backoff?: "fixed" | "exponential";
18
+ baseDelay?: number;
19
+ };
20
+ };
21
+ export declare function useUIConfig(): {
22
+ baseColor?: string;
23
+ borderRadius?: string;
24
+ };
25
+ export declare function useInterviewConfigSection(): NonNullable<InterviewWidgetConfig["interview"]>;
26
+ export declare function useSTTConfig(): {
27
+ provider?: "groq" | "deepgram";
28
+ model?: "whisper-large-v3-turbo" | (string & {});
29
+ language?: "en";
30
+ } | undefined;
31
+ export declare function useTTSConfig(): {
32
+ provider?: "piper";
33
+ } | undefined;
34
+ export {};
@@ -0,0 +1,26 @@
1
+ import { APIError, APIHookState } from '../types';
2
+ type UseQueryAPIOptions<T> = {
3
+ immediate?: boolean;
4
+ enabled?: boolean;
5
+ onError?: (error: APIError) => void;
6
+ onSuccess?: (data: T) => void;
7
+ onSettled?: (data: T | null, error: APIError | null) => void;
8
+ };
9
+ type UseMutationAPIOptions<T> = {
10
+ onError?: (error: APIError) => void;
11
+ onSuccess?: (data: T) => void;
12
+ onSettled?: (data: T | null, error: APIError | null) => void;
13
+ };
14
+ /**
15
+ * Hook for GET requests (queries) - auto-executes and provides refetch
16
+ */
17
+ export declare function useQueryAPI<T>(apiCall: () => Promise<T>, options?: UseQueryAPIOptions<T>): APIHookState<T> & {
18
+ refetch: () => Promise<void>;
19
+ };
20
+ /**
21
+ * Hook for mutations (POST/PUT/PATCH/DELETE) - manual execution with parameters
22
+ */
23
+ export declare function useMutationAPI<T, P extends any[] = []>(apiCall: (...args: P) => Promise<T>, options?: UseMutationAPIOptions<T>): APIHookState<T> & {
24
+ execute: (...args: P) => Promise<void>;
25
+ };
26
+ export {};
@@ -0,0 +1,6 @@
1
+ export declare const useDialog: (initialState?: boolean) => {
2
+ isOpen: boolean;
3
+ open: () => void;
4
+ close: () => void;
5
+ toggle: () => void;
6
+ };
@@ -0,0 +1,5 @@
1
+ import { InterviewAPI } from '../services/api/interview-api';
2
+ /**
3
+ * Provides a configured InterviewAPI instance
4
+ */
5
+ export declare function useInterviewAPI(): InterviewAPI;
@@ -0,0 +1,20 @@
1
+ import { STTConfig, STTError, STTRequest, STTResponse } from '../services/stt';
2
+ export interface UseSTTReturn {
3
+ startRecording: (maxDuration?: number) => Promise<void>;
4
+ stopRecording: () => Promise<Blob>;
5
+ transcribe: (audioBlob: Blob, options?: Partial<STTRequest>) => Promise<STTResponse>;
6
+ cancelRecording: () => void;
7
+ isRecording: boolean;
8
+ isTranscribing: boolean;
9
+ transcript: string | null;
10
+ error: STTError | null;
11
+ audioBlob: Blob | null;
12
+ }
13
+ export interface UseSTTOptions {
14
+ config?: Partial<STTConfig>;
15
+ onStart?: () => void;
16
+ onStop?: () => void;
17
+ onTranscriptionComplete?: (result: STTResponse) => void;
18
+ onError?: (error: STTError) => void;
19
+ }
20
+ export declare const useSTT: (options?: UseSTTOptions) => UseSTTReturn;
@@ -0,0 +1,12 @@
1
+ import { TimerService, TimerState, TimerConfig, TimerCallbacks } from '../services/timer/timer-service';
2
+ export interface UseTimerOptions {
3
+ config?: Partial<TimerConfig>;
4
+ callbacks?: TimerCallbacks;
5
+ }
6
+ export interface UseTimerReturn {
7
+ state: TimerState;
8
+ startQuestion: () => void;
9
+ nextPhase: () => void;
10
+ timerService: TimerService;
11
+ }
12
+ export declare function useTimer(options?: UseTimerOptions): UseTimerReturn;
@@ -0,0 +1,15 @@
1
+ import { TTSConfig, TTSRequest } from '../services/tts';
2
+ export interface UseTTSReturn {
3
+ speak: (text: string, options?: Partial<TTSRequest>) => Promise<void>;
4
+ stop: () => void;
5
+ isPlaying: boolean;
6
+ isLoading: boolean;
7
+ error: Error | null;
8
+ }
9
+ export interface UseTTSOptions {
10
+ config?: Partial<TTSConfig>;
11
+ onStart?: () => void;
12
+ onEnd?: () => void;
13
+ onError?: (error: Error) => void;
14
+ }
15
+ export declare const useTTS: (options?: UseTTSOptions) => UseTTSReturn;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
+ import { InterviewWidgetProvider } from './context/interview-widget-context';
1
2
  import { default as InterviewWidget } from './interview-widget';
2
- export { InterviewWidget };
3
3
  export * from './types';
4
- export { InterviewWidget as default };
4
+ export { InterviewWidget as default, InterviewWidget, InterviewWidgetProvider };
5
5
  declare global {
6
6
  interface Window {
7
7
  InterviewWidget: {
8
8
  InterviewWidget: typeof InterviewWidget;
9
+ InterviewWidgetProvider: typeof InterviewWidgetProvider;
9
10
  };
10
11
  React: any;
11
12
  ReactDOM: any;
@@ -0,0 +1,2 @@
1
+ export { interviewAPI, InterviewAPI } from './interview-api';
2
+ export type { APIError, APIErrorType, APIHookState } from '../../types';
@@ -0,0 +1,23 @@
1
+ import { InterviewQuestionPayload, InterviewQuestionResponse, InterviewWidgetConfig } from '../../types';
2
+ declare class InterviewAPI {
3
+ private config;
4
+ constructor(config?: InterviewWidgetConfig["api"]);
5
+ /**
6
+ * Update configuration
7
+ */
8
+ updateConfig(config: InterviewWidgetConfig["api"]): void;
9
+ /**
10
+ * Get default headers for API requests
11
+ */
12
+ private getHeaders;
13
+ /**
14
+ * Get base URL from config with fallback
15
+ */
16
+ private getBaseUrl;
17
+ /**
18
+ * Get questions for an interview
19
+ */
20
+ generateQuestion({ interviewId, isInterviewDone, qnaId, question, answer, answerDuration, }: InterviewQuestionPayload): Promise<InterviewQuestionResponse>;
21
+ }
22
+ export declare const interviewAPI: InterviewAPI;
23
+ export { InterviewAPI };
@@ -0,0 +1 @@
1
+ export { sttService, STTService, STTError, type STTConfig, type STTRequest, type STTResponse, type RecordingEvents, } from './stt-service';
@@ -0,0 +1,78 @@
1
+ export interface STTConfig {
2
+ baseUrl?: string;
3
+ provider?: string;
4
+ model?: string;
5
+ language?: string;
6
+ includeTimestamps?: boolean;
7
+ temperature?: number;
8
+ }
9
+ export interface STTRequest {
10
+ audioBlob: Blob;
11
+ model?: string;
12
+ language?: string;
13
+ includeTimestamps?: boolean;
14
+ temperature?: number;
15
+ }
16
+ export interface STTResponse {
17
+ transcript: string;
18
+ confidence?: number;
19
+ language?: string;
20
+ duration?: number;
21
+ }
22
+ export interface RecordingEvents {
23
+ onStart?: () => void;
24
+ onStop?: () => void;
25
+ onDataAvailable?: (blob: Blob) => void;
26
+ onError?: (error: Error) => void;
27
+ }
28
+ export declare class STTError extends Error {
29
+ readonly code: string;
30
+ readonly recoverable: boolean;
31
+ constructor(message: string, code: string, recoverable?: boolean);
32
+ }
33
+ declare class STTService {
34
+ private config;
35
+ private mediaRecorder;
36
+ private audioChunks;
37
+ private recordingStream;
38
+ private autoStopTimeoutId;
39
+ constructor(config?: STTConfig);
40
+ /**
41
+ * Update STT configuration
42
+ */
43
+ updateConfig(config: Partial<STTConfig>): void;
44
+ /**
45
+ * Check if browser supports audio recording
46
+ */
47
+ isRecordingSupported(): boolean;
48
+ /**
49
+ * Start recording audio from user's microphone
50
+ */
51
+ startRecording(maxDuration?: number, events?: RecordingEvents): Promise<void>;
52
+ /**
53
+ * Stop recording and return the audio blob
54
+ */
55
+ stopRecording(): Promise<Blob>;
56
+ /**
57
+ * Transcribe audio blob using the STT API
58
+ */
59
+ transcribe(request: STTRequest): Promise<STTResponse>;
60
+ /**
61
+ * Cancel current recording without processing
62
+ */
63
+ cancelRecording(): void;
64
+ /**
65
+ * Check if currently recording
66
+ */
67
+ isRecording(): boolean;
68
+ /**
69
+ * Get supported MIME type for recording
70
+ */
71
+ private getSupportedMimeType;
72
+ /**
73
+ * Clean up recording resources
74
+ */
75
+ private cleanup;
76
+ }
77
+ export declare const sttService: STTService;
78
+ export { STTService };