@sage-rsc/talking-head-react 1.0.27 → 1.0.29

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.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./index-COqTUp83.cjs");exports.CurriculumLearning=i.CurriculumLearning;exports.TalkingHeadAvatar=i.TalkingHeadAvatar;exports.TalkingHeadComponent=i.TalkingHeadComponent;exports.animations=i.animations;exports.getActiveTTSConfig=i.getActiveTTSConfig;exports.getAnimation=i.getAnimation;exports.getVoiceOptions=i.getVoiceOptions;exports.hasAnimation=i.hasAnimation;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./index-C3A1_CcE.cjs");exports.CurriculumLearning=i.CurriculumLearning;exports.TalkingHeadAvatar=i.TalkingHeadAvatar;exports.TalkingHeadComponent=i.TalkingHeadComponent;exports.animations=i.animations;exports.getActiveTTSConfig=i.getActiveTTSConfig;exports.getAnimation=i.getAnimation;exports.getVoiceOptions=i.getVoiceOptions;exports.hasAnimation=i.hasAnimation;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as n, T as s, a as t, d as e, b as o, g, c as m, h as r } from "./index-DPiBXfzj.js";
1
+ import { C as n, T as s, a as t, d as e, b as o, g, c as m, h as r } from "./index-BvDk1TRw.js";
2
2
  export {
3
3
  n as CurriculumLearning,
4
4
  s as TalkingHeadAvatar,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sage-rsc/talking-head-react",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "A reusable React component for 3D talking avatars with lip-sync and text-to-speech",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -51,6 +51,11 @@ const CurriculumLearning = forwardRef(({
51
51
  onCustomAction
52
52
  });
53
53
 
54
+ // Refs for functions to avoid circular dependencies
55
+ const startTeachingRef = useRef(null);
56
+ const nextLessonRef = useRef(null);
57
+ const completeLessonRef = useRef(null);
58
+
54
59
  // Update callbacks ref when they change
55
60
  useEffect(() => {
56
61
  callbacksRef.current = {
@@ -111,13 +116,20 @@ const CurriculumLearning = forwardRef(({
111
116
  return false;
112
117
  }, []);
113
118
 
114
- // Complete current lesson
119
+ // Complete current lesson - defined before it's used to avoid circular dependency
115
120
  const completeLesson = useCallback(() => {
116
121
  stateRef.current.lessonCompleted = true;
117
122
  stateRef.current.isQuestionMode = false;
118
123
 
119
- const percentage = Math.round((stateRef.current.score / stateRef.current.totalQuestions) * 100);
120
- let feedbackMessage = `Congratulations! You've completed this lesson with a score of ${stateRef.current.score} out of ${stateRef.current.totalQuestions} (${percentage}%). `;
124
+ const percentage = stateRef.current.totalQuestions > 0
125
+ ? Math.round((stateRef.current.score / stateRef.current.totalQuestions) * 100)
126
+ : 100;
127
+ let feedbackMessage = `Congratulations! You've completed this lesson`;
128
+ if (stateRef.current.totalQuestions > 0) {
129
+ feedbackMessage += ` with a score of ${stateRef.current.score} out of ${stateRef.current.totalQuestions} (${percentage}%). `;
130
+ } else {
131
+ feedbackMessage += `! `;
132
+ }
121
133
 
122
134
  if (percentage >= 80) {
123
135
  feedbackMessage += "Excellent work! You have a great understanding of this topic.";
@@ -150,7 +162,7 @@ const CurriculumLearning = forwardRef(({
150
162
  if (animations.lessonComplete) {
151
163
  try {
152
164
  avatarRef.current.playAnimation(animations.lessonComplete, true);
153
- } catch (error) {
165
+ } catch (error) {
154
166
  avatarRef.current.playCelebration();
155
167
  }
156
168
  }
@@ -165,12 +177,15 @@ const CurriculumLearning = forwardRef(({
165
177
  lipsyncLang: defaultAvatarConfig.lipsyncLang,
166
178
  onSpeechEnd: () => {
167
179
  // Add a small delay after speech ends for natural flow
168
- setTimeout(() => {
169
- nextLesson();
180
+ setTimeout(() => {
181
+ // Use ref to avoid circular dependency
182
+ if (nextLessonRef.current) {
183
+ nextLessonRef.current();
184
+ }
170
185
  }, 1000);
171
186
  }
172
187
  });
173
- } else {
188
+ } else {
174
189
  // This is the last lesson, complete curriculum instead
175
190
  avatarRef.current.speakText(feedbackMessage, {
176
191
  lipsyncLang: defaultAvatarConfig.lipsyncLang,
@@ -183,7 +198,10 @@ const CurriculumLearning = forwardRef(({
183
198
  });
184
199
  }
185
200
  }
186
- }, [animations.lessonComplete, curriculum, nextLesson, completeCurriculum, defaultAvatarConfig]);
201
+ }, [animations.lessonComplete, curriculum, completeCurriculum, defaultAvatarConfig]);
202
+
203
+ // Assign ref immediately after function is defined
204
+ completeLessonRef.current = completeLesson;
187
205
 
188
206
  // Complete entire curriculum
189
207
  const completeCurriculum = useCallback(() => {
@@ -308,9 +326,12 @@ const CurriculumLearning = forwardRef(({
308
326
  }
309
327
  }
310
328
  } else {
311
- completeLesson();
329
+ // Use ref to avoid circular dependency
330
+ if (completeLessonRef.current) {
331
+ completeLessonRef.current();
332
+ }
312
333
  }
313
- }, [animations.nextQuestion, getCurrentLesson, completeLesson, getCurrentQuestion, defaultAvatarConfig]);
334
+ }, [animations.nextQuestion, getCurrentLesson, getCurrentQuestion, defaultAvatarConfig]);
314
335
 
315
336
  // Move to next lesson
316
337
  const nextLesson = useCallback(() => {
@@ -337,13 +358,18 @@ const CurriculumLearning = forwardRef(({
337
358
 
338
359
  // Automatically start teaching the next lesson after a brief pause
339
360
  setTimeout(() => {
340
- startTeaching();
361
+ if (startTeachingRef.current) {
362
+ startTeachingRef.current();
363
+ }
341
364
  }, 500);
342
365
  }
343
366
  } else {
344
367
  completeCurriculum();
345
368
  }
346
- }, [curriculum, completeCurriculum, startTeaching]);
369
+ }, [curriculum, completeCurriculum]);
370
+
371
+ // Assign ref immediately after function is defined
372
+ nextLessonRef.current = nextLesson;
347
373
 
348
374
  // Start teaching the lesson
349
375
  const startTeaching = useCallback(() => {
@@ -391,11 +417,17 @@ const CurriculumLearning = forwardRef(({
391
417
  if (currentLesson.questions && currentLesson.questions.length > 0) {
392
418
  startQuestions();
393
419
  } else {
394
- completeLesson();
420
+ // No questions, complete the lesson using ref to avoid circular dependency
421
+ if (completeLessonRef.current) {
422
+ completeLessonRef.current();
423
+ }
395
424
  }
396
425
  }, 8000);
397
426
  }
398
- }, [animations.teaching, getCurrentLesson, startQuestions, completeLesson, defaultAvatarConfig]);
427
+ }, [animations.teaching, getCurrentLesson, startQuestions, defaultAvatarConfig]);
428
+
429
+ // Assign ref immediately after function is defined
430
+ startTeachingRef.current = startTeaching;
399
431
 
400
432
  // Handle answer selection
401
433
  const handleAnswerSelect = useCallback((answer) => {
@@ -526,16 +558,18 @@ const CurriculumLearning = forwardRef(({
526
558
  stateRef.current.totalQuestions = 0;
527
559
  }, []);
528
560
 
529
- // Handle avatar ready callback
561
+ // Handle avatar ready callback - use ref to avoid circular dependency
530
562
  const handleAvatarReady = useCallback((talkingHead) => {
531
563
  console.log('Avatar is ready!', talkingHead);
532
564
  const currentLesson = getCurrentLesson();
533
565
  if (autoStart && currentLesson?.avatar_script) {
534
566
  setTimeout(() => {
535
- startTeaching();
567
+ if (startTeachingRef.current) {
568
+ startTeachingRef.current();
569
+ }
536
570
  }, 1000);
537
571
  }
538
- }, [autoStart, getCurrentLesson, startTeaching]);
572
+ }, [autoStart, getCurrentLesson]);
539
573
 
540
574
  // Expose methods via ref (for external control)
541
575
  useImperativeHandle(ref, () => ({