@intellectif/lk-react 23.1.0 → 23.1.2

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 (360) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +9 -5
  3. package/dist/ActivityErrorBoundary-B379hvtL.cjs +39 -0
  4. package/dist/ActivityErrorBoundary-B379hvtL.cjs.map +1 -0
  5. package/dist/ActivityErrorBoundary-Dw6SbWv3.js +34 -0
  6. package/dist/ActivityErrorBoundary-Dw6SbWv3.js.map +1 -0
  7. package/dist/ActivityMedia-CQQTRNl7.cjs +641 -0
  8. package/dist/ActivityMedia-CQQTRNl7.cjs.map +1 -0
  9. package/dist/ActivityMedia-vDiP-Psa.js +636 -0
  10. package/dist/ActivityMedia-vDiP-Psa.js.map +1 -0
  11. package/dist/ActivityPreview-1hhTkYuj.js +240 -0
  12. package/dist/ActivityPreview-1hhTkYuj.js.map +1 -0
  13. package/dist/ActivityPreview-BKr34exz.cjs +245 -0
  14. package/dist/ActivityPreview-BKr34exz.cjs.map +1 -0
  15. package/dist/ActivitySequence-CkX87pfB.js +839 -0
  16. package/dist/ActivitySequence-CkX87pfB.js.map +1 -0
  17. package/dist/ActivitySequence-CmoSyDnp.cjs +844 -0
  18. package/dist/ActivitySequence-CmoSyDnp.cjs.map +1 -0
  19. package/dist/Dictation-BlxRp-3k.js +926 -0
  20. package/dist/Dictation-BlxRp-3k.js.map +1 -0
  21. package/dist/Dictation-jECzL88E.cjs +931 -0
  22. package/dist/Dictation-jECzL88E.cjs.map +1 -0
  23. package/dist/FeedbackRegion-BNNMtTY-.cjs +108 -0
  24. package/dist/FeedbackRegion-BNNMtTY-.cjs.map +1 -0
  25. package/dist/FeedbackRegion-CyPSp8bA.js +85 -0
  26. package/dist/FeedbackRegion-CyPSp8bA.js.map +1 -0
  27. package/dist/FillInTheBlanks-B6xzqYXx.js +474 -0
  28. package/dist/FillInTheBlanks-B6xzqYXx.js.map +1 -0
  29. package/dist/FillInTheBlanks-BpKhdHg2.cjs +479 -0
  30. package/dist/FillInTheBlanks-BpKhdHg2.cjs.map +1 -0
  31. package/dist/GapSelect-DUSiaEQH.js +441 -0
  32. package/dist/GapSelect-DUSiaEQH.js.map +1 -0
  33. package/dist/GapSelect-payTq_Zn.cjs +446 -0
  34. package/dist/GapSelect-payTq_Zn.cjs.map +1 -0
  35. package/dist/InteractiveVideo-BguGv-HA.cjs +2955 -0
  36. package/dist/InteractiveVideo-BguGv-HA.cjs.map +1 -0
  37. package/dist/InteractiveVideo-Cg2jbU3j.js +2944 -0
  38. package/dist/InteractiveVideo-Cg2jbU3j.js.map +1 -0
  39. package/dist/LkAiProvider-DAPpA3PQ.d.cts +84 -0
  40. package/dist/LkAiProvider-DAPpA3PQ.d.cts.map +1 -0
  41. package/dist/LkAiProvider-QdEcIhoo.d.ts +84 -0
  42. package/dist/LkAiProvider-QdEcIhoo.d.ts.map +1 -0
  43. package/dist/LkIntlProvider-D_FdYXjQ.js +375 -0
  44. package/dist/LkIntlProvider-D_FdYXjQ.js.map +1 -0
  45. package/dist/LkIntlProvider-oi57lYB0.cjs +410 -0
  46. package/dist/LkIntlProvider-oi57lYB0.cjs.map +1 -0
  47. package/dist/MultipleChoice-COn5MtKY.cjs +433 -0
  48. package/dist/MultipleChoice-COn5MtKY.cjs.map +1 -0
  49. package/dist/MultipleChoice-Dra0_KYD.js +428 -0
  50. package/dist/MultipleChoice-Dra0_KYD.js.map +1 -0
  51. package/dist/PronunciationFeedback-DlMPGjkR.cjs +831 -0
  52. package/dist/PronunciationFeedback-DlMPGjkR.cjs.map +1 -0
  53. package/dist/PronunciationFeedback-Dxd6XPkO.js +772 -0
  54. package/dist/PronunciationFeedback-Dxd6XPkO.js.map +1 -0
  55. package/dist/ReadAloud-C8RhaUqV.js +1092 -0
  56. package/dist/{chunk-DC4CQCK5.js.map → ReadAloud-C8RhaUqV.js.map} +1 -1
  57. package/dist/ReadAloud-akDehitT.cjs +1103 -0
  58. package/dist/ReadAloud-akDehitT.cjs.map +1 -0
  59. package/dist/StimulusPanel-BgzByfkb.js +74 -0
  60. package/dist/StimulusPanel-BgzByfkb.js.map +1 -0
  61. package/dist/StimulusPanel-b66gaN3i.cjs +79 -0
  62. package/dist/StimulusPanel-b66gaN3i.cjs.map +1 -0
  63. package/dist/ThemeProvider-B6DyGqzh.d.cts +62 -0
  64. package/dist/ThemeProvider-B6DyGqzh.d.cts.map +1 -0
  65. package/dist/ThemeProvider-BCrxBaY-.d.ts +62 -0
  66. package/dist/ThemeProvider-BCrxBaY-.d.ts.map +1 -0
  67. package/dist/ThemeProvider-BRN1tj4n.cjs +187 -0
  68. package/dist/ThemeProvider-BRN1tj4n.cjs.map +1 -0
  69. package/dist/ThemeProvider-C7K9iMLX.js +158 -0
  70. package/dist/ThemeProvider-C7K9iMLX.js.map +1 -0
  71. package/dist/WrittenResponse-Bj3eFmGl.cjs +491 -0
  72. package/dist/WrittenResponse-Bj3eFmGl.cjs.map +1 -0
  73. package/dist/WrittenResponse-Cl8G6nO_.js +486 -0
  74. package/dist/WrittenResponse-Cl8G6nO_.js.map +1 -0
  75. package/dist/ai/LkAiProvider.cjs +34 -14
  76. package/dist/ai/LkAiProvider.cjs.map +1 -1
  77. package/dist/ai/LkAiProvider.d.cts +2 -83
  78. package/dist/ai/LkAiProvider.d.ts +2 -83
  79. package/dist/ai/LkAiProvider.js +33 -2
  80. package/dist/ai/LkAiProvider.js.map +1 -1
  81. package/dist/ai/useAiHelp.cjs +7 -25
  82. package/dist/ai/useAiHelp.d.cts +175 -177
  83. package/dist/ai/useAiHelp.d.cts.map +1 -0
  84. package/dist/ai/useAiHelp.d.ts +175 -177
  85. package/dist/ai/useAiHelp.d.ts.map +1 -0
  86. package/dist/ai/useAiHelp.js +3 -4
  87. package/dist/components/ActivityPreview.cjs +3 -29
  88. package/dist/components/ActivityPreview.d.cts +2 -81
  89. package/dist/components/ActivityPreview.d.ts +2 -81
  90. package/dist/components/ActivityPreview.js +2 -20
  91. package/dist/components/ActivitySequence.cjs +3 -30
  92. package/dist/components/ActivitySequence.d.cts +2 -432
  93. package/dist/components/ActivitySequence.d.ts +2 -432
  94. package/dist/components/ActivitySequence.js +2 -21
  95. package/dist/components/Dictation.cjs +4 -21
  96. package/dist/components/Dictation.d.cts +2 -19
  97. package/dist/components/Dictation.d.ts +2 -19
  98. package/dist/components/Dictation.js +3 -12
  99. package/dist/components/FillInTheBlanks.cjs +4 -20
  100. package/dist/components/FillInTheBlanks.d.cts +2 -30
  101. package/dist/components/FillInTheBlanks.d.ts +2 -30
  102. package/dist/components/FillInTheBlanks.js +3 -11
  103. package/dist/components/GapSelect.cjs +4 -20
  104. package/dist/components/GapSelect.d.cts +2 -27
  105. package/dist/components/GapSelect.d.ts +2 -27
  106. package/dist/components/GapSelect.js +3 -11
  107. package/dist/components/InteractiveVideo.cjs +5 -32
  108. package/dist/components/InteractiveVideo.d.cts +3 -291
  109. package/dist/components/InteractiveVideo.d.ts +3 -291
  110. package/dist/components/InteractiveVideo.js +3 -19
  111. package/dist/components/MultipleChoice.cjs +4 -20
  112. package/dist/components/MultipleChoice.d.cts +2 -26
  113. package/dist/components/MultipleChoice.d.ts +2 -26
  114. package/dist/components/MultipleChoice.js +3 -11
  115. package/dist/components/PronunciationFeedback.cjs +4 -17
  116. package/dist/components/PronunciationFeedback.d.cts +2 -90
  117. package/dist/components/PronunciationFeedback.d.ts +2 -90
  118. package/dist/components/PronunciationFeedback.js +3 -8
  119. package/dist/components/ReadAloud.cjs +4 -22
  120. package/dist/components/ReadAloud.d.cts +7 -11
  121. package/dist/components/ReadAloud.d.cts.map +1 -0
  122. package/dist/components/ReadAloud.d.ts +7 -11
  123. package/dist/components/ReadAloud.d.ts.map +1 -0
  124. package/dist/components/ReadAloud.js +3 -13
  125. package/dist/components/StimulusPanel.cjs +3 -14
  126. package/dist/components/StimulusPanel.d.cts +2 -51
  127. package/dist/components/StimulusPanel.d.ts +2 -51
  128. package/dist/components/StimulusPanel.js +2 -5
  129. package/dist/components/WrittenResponse.cjs +4 -19
  130. package/dist/components/WrittenResponse.d.cts +3 -18
  131. package/dist/components/WrittenResponse.d.ts +3 -18
  132. package/dist/components/WrittenResponse.js +3 -10
  133. package/dist/direction-Dq0_HtA5.js +183 -0
  134. package/dist/direction-Dq0_HtA5.js.map +1 -0
  135. package/dist/direction-K1pj0HCA.cjs +200 -0
  136. package/dist/direction-K1pj0HCA.cjs.map +1 -0
  137. package/dist/hooks/useActivityState.cjs +28 -10
  138. package/dist/hooks/useActivityState.cjs.map +1 -1
  139. package/dist/hooks/useActivityState.d.cts +25 -24
  140. package/dist/hooks/useActivityState.d.cts.map +1 -0
  141. package/dist/hooks/useActivityState.d.ts +25 -24
  142. package/dist/hooks/useActivityState.d.ts.map +1 -0
  143. package/dist/hooks/useActivityState.js +28 -2
  144. package/dist/hooks/useActivityState.js.map +1 -1
  145. package/dist/hooks/useSpeechRecorder.cjs +5 -16
  146. package/dist/hooks/useSpeechRecorder.d.cts +2 -127
  147. package/dist/hooks/useSpeechRecorder.d.ts +2 -127
  148. package/dist/hooks/useSpeechRecorder.js +3 -3
  149. package/dist/hooks/useXAPI.cjs +126 -10
  150. package/dist/hooks/useXAPI.cjs.map +1 -1
  151. package/dist/hooks/useXAPI.d.cts +14 -14
  152. package/dist/hooks/useXAPI.d.cts.map +1 -0
  153. package/dist/hooks/useXAPI.d.ts +14 -14
  154. package/dist/hooks/useXAPI.d.ts.map +1 -0
  155. package/dist/hooks/useXAPI.js +126 -2
  156. package/dist/hooks/useXAPI.js.map +1 -1
  157. package/dist/i18n/LkIntlProvider.cjs +9 -32
  158. package/dist/i18n/LkIntlProvider.d.cts +34 -38
  159. package/dist/i18n/LkIntlProvider.d.cts.map +1 -0
  160. package/dist/i18n/LkIntlProvider.d.ts +34 -38
  161. package/dist/i18n/LkIntlProvider.d.ts.map +1 -0
  162. package/dist/i18n/LkIntlProvider.js +3 -3
  163. package/dist/index-6P4rJHrJ.d.cts +432 -0
  164. package/dist/index-6P4rJHrJ.d.cts.map +1 -0
  165. package/dist/index-90CX504k.d.ts +90 -0
  166. package/dist/index-90CX504k.d.ts.map +1 -0
  167. package/dist/index-B_SgnjsC.d.cts +291 -0
  168. package/dist/index-B_SgnjsC.d.cts.map +1 -0
  169. package/dist/index-BavVW5z5.d.cts +25 -0
  170. package/dist/index-BavVW5z5.d.cts.map +1 -0
  171. package/dist/index-BhHv6Fiu.d.cts +28 -0
  172. package/dist/index-BhHv6Fiu.d.cts.map +1 -0
  173. package/dist/index-Bsu8VciA.d.ts +432 -0
  174. package/dist/index-Bsu8VciA.d.ts.map +1 -0
  175. package/dist/index-C1KGpD1k.d.ts +49 -0
  176. package/dist/index-C1KGpD1k.d.ts.map +1 -0
  177. package/dist/index-CKTpYTCC.d.cts +49 -0
  178. package/dist/index-CKTpYTCC.d.cts.map +1 -0
  179. package/dist/index-CO_SRFJj.d.ts +16 -0
  180. package/dist/index-CO_SRFJj.d.ts.map +1 -0
  181. package/dist/index-CSsuUsP7.d.cts +124 -0
  182. package/dist/index-CSsuUsP7.d.cts.map +1 -0
  183. package/dist/index-CunUyeuN.d.cts +78 -0
  184. package/dist/index-CunUyeuN.d.cts.map +1 -0
  185. package/dist/index-CzfRzks6.d.cts +90 -0
  186. package/dist/index-CzfRzks6.d.cts.map +1 -0
  187. package/dist/index-D14xtpBS.d.cts +24 -0
  188. package/dist/index-D14xtpBS.d.cts.map +1 -0
  189. package/dist/index-DHRPAPZf.d.ts +291 -0
  190. package/dist/index-DHRPAPZf.d.ts.map +1 -0
  191. package/dist/index-DLV6cK26.d.cts +16 -0
  192. package/dist/index-DLV6cK26.d.cts.map +1 -0
  193. package/dist/index-DbCCQ9cP.d.ts +124 -0
  194. package/dist/index-DbCCQ9cP.d.ts.map +1 -0
  195. package/dist/index-DeV5B2m5.d.ts +24 -0
  196. package/dist/index-DeV5B2m5.d.ts.map +1 -0
  197. package/dist/index-TZCJVSge.d.ts +28 -0
  198. package/dist/index-TZCJVSge.d.ts.map +1 -0
  199. package/dist/index-ZVvLHsd3.d.ts +25 -0
  200. package/dist/index-ZVvLHsd3.d.ts.map +1 -0
  201. package/dist/index-eQwBgpSw.d.ts +78 -0
  202. package/dist/index-eQwBgpSw.d.ts.map +1 -0
  203. package/dist/index.cjs +118 -163
  204. package/dist/index.cjs.map +1 -1
  205. package/dist/index.d.cts +20 -24
  206. package/dist/index.d.ts +20 -24
  207. package/dist/index.js +84 -29
  208. package/dist/index.js.map +1 -1
  209. package/dist/theme/ThemeProvider.cjs +8 -28
  210. package/dist/theme/ThemeProvider.d.cts +2 -59
  211. package/dist/theme/ThemeProvider.d.ts +2 -59
  212. package/dist/theme/ThemeProvider.js +3 -3
  213. package/dist/tries-CbbtZkdG.cjs +363 -0
  214. package/dist/tries-CbbtZkdG.cjs.map +1 -0
  215. package/dist/tries-DTHSrLCm.js +310 -0
  216. package/dist/tries-DTHSrLCm.js.map +1 -0
  217. package/dist/types-BOQd93x3.d.cts +994 -0
  218. package/dist/types-BOQd93x3.d.cts.map +1 -0
  219. package/dist/types-HIrgF_mS.d.ts +994 -0
  220. package/dist/types-HIrgF_mS.d.ts.map +1 -0
  221. package/dist/useAiHelp-B-ccDL5Q.js +906 -0
  222. package/dist/useAiHelp-B-ccDL5Q.js.map +1 -0
  223. package/dist/useAiHelp-h9yOLFqt.cjs +995 -0
  224. package/dist/useAiHelp-h9yOLFqt.cjs.map +1 -0
  225. package/dist/useSpeechRecorder--O_f-xvt.cjs +720 -0
  226. package/dist/useSpeechRecorder--O_f-xvt.cjs.map +1 -0
  227. package/dist/useSpeechRecorder-DtAYvl02.d.cts +154 -0
  228. package/dist/useSpeechRecorder-DtAYvl02.d.cts.map +1 -0
  229. package/dist/useSpeechRecorder-DtAYvl02.d.ts +154 -0
  230. package/dist/useSpeechRecorder-DtAYvl02.d.ts.map +1 -0
  231. package/dist/useSpeechRecorder-zIi9Dlw8.js +709 -0
  232. package/dist/useSpeechRecorder-zIi9Dlw8.js.map +1 -0
  233. package/package.json +10 -11
  234. package/dist/WrittenResponse-B7A5gHMj.d.ts +0 -115
  235. package/dist/WrittenResponse-BpL9p2Hn.d.cts +0 -115
  236. package/dist/ai/useAiHelp.cjs.map +0 -1
  237. package/dist/ai/useAiHelp.js.map +0 -1
  238. package/dist/chunk-2PNSVBLQ.cjs +0 -54
  239. package/dist/chunk-2PNSVBLQ.cjs.map +0 -1
  240. package/dist/chunk-2TW6WLBC.js +0 -80
  241. package/dist/chunk-2TW6WLBC.js.map +0 -1
  242. package/dist/chunk-4ZZWZSWI.js +0 -61
  243. package/dist/chunk-4ZZWZSWI.js.map +0 -1
  244. package/dist/chunk-6N43WDVG.js +0 -29
  245. package/dist/chunk-6N43WDVG.js.map +0 -1
  246. package/dist/chunk-7ALBSPYR.cjs +0 -436
  247. package/dist/chunk-7ALBSPYR.cjs.map +0 -1
  248. package/dist/chunk-7NFY3M3W.js +0 -234
  249. package/dist/chunk-7NFY3M3W.js.map +0 -1
  250. package/dist/chunk-7SB2MJA4.js +0 -29
  251. package/dist/chunk-7SB2MJA4.js.map +0 -1
  252. package/dist/chunk-ABJJ3LII.js +0 -434
  253. package/dist/chunk-ABJJ3LII.js.map +0 -1
  254. package/dist/chunk-BIGGXHAW.cjs +0 -342
  255. package/dist/chunk-BIGGXHAW.cjs.map +0 -1
  256. package/dist/chunk-C7QZE5BI.js +0 -430
  257. package/dist/chunk-C7QZE5BI.js.map +0 -1
  258. package/dist/chunk-CWTUWNV3.cjs +0 -2937
  259. package/dist/chunk-CWTUWNV3.cjs.map +0 -1
  260. package/dist/chunk-DC4CQCK5.js +0 -915
  261. package/dist/chunk-DS6HN3YR.cjs +0 -496
  262. package/dist/chunk-DS6HN3YR.cjs.map +0 -1
  263. package/dist/chunk-FDQR4GAZ.js +0 -240
  264. package/dist/chunk-FDQR4GAZ.js.map +0 -1
  265. package/dist/chunk-FKGMSOJF.js +0 -394
  266. package/dist/chunk-FKGMSOJF.js.map +0 -1
  267. package/dist/chunk-G6PXJ2SA.js +0 -823
  268. package/dist/chunk-G6PXJ2SA.js.map +0 -1
  269. package/dist/chunk-HNLRVRQR.js +0 -335
  270. package/dist/chunk-HNLRVRQR.js.map +0 -1
  271. package/dist/chunk-J3C72RPK.cjs +0 -31
  272. package/dist/chunk-J3C72RPK.cjs.map +0 -1
  273. package/dist/chunk-K63VPFOV.cjs +0 -134
  274. package/dist/chunk-K63VPFOV.cjs.map +0 -1
  275. package/dist/chunk-KFLIDTDU.cjs +0 -825
  276. package/dist/chunk-KFLIDTDU.cjs.map +0 -1
  277. package/dist/chunk-KHKH5LCT.cjs +0 -250
  278. package/dist/chunk-KHKH5LCT.cjs.map +0 -1
  279. package/dist/chunk-LBEKRN6Y.cjs +0 -664
  280. package/dist/chunk-LBEKRN6Y.cjs.map +0 -1
  281. package/dist/chunk-LPUWXIPR.cjs +0 -578
  282. package/dist/chunk-LPUWXIPR.cjs.map +0 -1
  283. package/dist/chunk-MCO52PV5.js +0 -520
  284. package/dist/chunk-MCO52PV5.js.map +0 -1
  285. package/dist/chunk-MKXEM2C5.cjs +0 -396
  286. package/dist/chunk-MKXEM2C5.cjs.map +0 -1
  287. package/dist/chunk-MXNC5UNO.js +0 -563
  288. package/dist/chunk-MXNC5UNO.js.map +0 -1
  289. package/dist/chunk-NAK55BYU.cjs +0 -859
  290. package/dist/chunk-NAK55BYU.cjs.map +0 -1
  291. package/dist/chunk-NDBMKGQ5.cjs +0 -599
  292. package/dist/chunk-NDBMKGQ5.cjs.map +0 -1
  293. package/dist/chunk-OD65OZIW.cjs +0 -159
  294. package/dist/chunk-OD65OZIW.cjs.map +0 -1
  295. package/dist/chunk-ORT3KLGI.js +0 -50
  296. package/dist/chunk-ORT3KLGI.js.map +0 -1
  297. package/dist/chunk-PNNUPUH4.cjs +0 -82
  298. package/dist/chunk-PNNUPUH4.cjs.map +0 -1
  299. package/dist/chunk-PWHECW6N.js +0 -2934
  300. package/dist/chunk-PWHECW6N.js.map +0 -1
  301. package/dist/chunk-RBS5A2DF.js +0 -857
  302. package/dist/chunk-RBS5A2DF.js.map +0 -1
  303. package/dist/chunk-RPWUDXG5.cjs +0 -63
  304. package/dist/chunk-RPWUDXG5.cjs.map +0 -1
  305. package/dist/chunk-TCDJY3H6.js +0 -494
  306. package/dist/chunk-TCDJY3H6.js.map +0 -1
  307. package/dist/chunk-TP5UMRAU.cjs +0 -918
  308. package/dist/chunk-TP5UMRAU.cjs.map +0 -1
  309. package/dist/chunk-TS7J6DTY.js +0 -597
  310. package/dist/chunk-TS7J6DTY.js.map +0 -1
  311. package/dist/chunk-TUVENMXB.cjs +0 -20
  312. package/dist/chunk-TUVENMXB.cjs.map +0 -1
  313. package/dist/chunk-UDCQTOVU.cjs +0 -523
  314. package/dist/chunk-UDCQTOVU.cjs.map +0 -1
  315. package/dist/chunk-UHKZXOXD.js +0 -128
  316. package/dist/chunk-UHKZXOXD.js.map +0 -1
  317. package/dist/chunk-V6BA44DS.cjs +0 -236
  318. package/dist/chunk-V6BA44DS.cjs.map +0 -1
  319. package/dist/chunk-XO5R73Y4.js +0 -653
  320. package/dist/chunk-XO5R73Y4.js.map +0 -1
  321. package/dist/chunk-XOR4MPEN.cjs +0 -31
  322. package/dist/chunk-XOR4MPEN.cjs.map +0 -1
  323. package/dist/chunk-YORQQXGO.js +0 -155
  324. package/dist/chunk-YORQQXGO.js.map +0 -1
  325. package/dist/chunk-YY4PFR3Z.cjs +0 -432
  326. package/dist/chunk-YY4PFR3Z.cjs.map +0 -1
  327. package/dist/chunk-ZPI6Q42R.js +0 -17
  328. package/dist/chunk-ZPI6Q42R.js.map +0 -1
  329. package/dist/components/ActivityPreview.cjs.map +0 -1
  330. package/dist/components/ActivityPreview.js.map +0 -1
  331. package/dist/components/ActivitySequence.cjs.map +0 -1
  332. package/dist/components/ActivitySequence.js.map +0 -1
  333. package/dist/components/Dictation.cjs.map +0 -1
  334. package/dist/components/Dictation.js.map +0 -1
  335. package/dist/components/FillInTheBlanks.cjs.map +0 -1
  336. package/dist/components/FillInTheBlanks.js.map +0 -1
  337. package/dist/components/GapSelect.cjs.map +0 -1
  338. package/dist/components/GapSelect.js.map +0 -1
  339. package/dist/components/InteractiveVideo.cjs.map +0 -1
  340. package/dist/components/InteractiveVideo.js.map +0 -1
  341. package/dist/components/MultipleChoice.cjs.map +0 -1
  342. package/dist/components/MultipleChoice.js.map +0 -1
  343. package/dist/components/PronunciationFeedback.cjs.map +0 -1
  344. package/dist/components/PronunciationFeedback.js.map +0 -1
  345. package/dist/components/ReadAloud.cjs.map +0 -1
  346. package/dist/components/ReadAloud.js.map +0 -1
  347. package/dist/components/StimulusPanel.cjs.map +0 -1
  348. package/dist/components/StimulusPanel.js.map +0 -1
  349. package/dist/components/WrittenResponse.cjs.map +0 -1
  350. package/dist/components/WrittenResponse.js.map +0 -1
  351. package/dist/hooks/useSpeechRecorder.cjs.map +0 -1
  352. package/dist/hooks/useSpeechRecorder.js.map +0 -1
  353. package/dist/i18n/LkIntlProvider.cjs.map +0 -1
  354. package/dist/i18n/LkIntlProvider.js.map +0 -1
  355. package/dist/machine-CuwKqWXC.d.cts +0 -26
  356. package/dist/machine-CuwKqWXC.d.ts +0 -26
  357. package/dist/theme/ThemeProvider.cjs.map +0 -1
  358. package/dist/theme/ThemeProvider.js.map +0 -1
  359. package/dist/types-C4IsUQsK.d.ts +0 -989
  360. package/dist/types-CJgZWtl4.d.cts +0 -989
@@ -1,127 +1,2 @@
1
- import { a as SpeechRecorderStatus, S as SpeechRecorderError, R as RecordedTake } from '../machine-CuwKqWXC.js';
2
-
3
- /**
4
- * The audio worklet module `useSpeechRecorder` captures through, as source
5
- * text — exported so an application with a strict Content-Security-Policy can
6
- * serve it itself.
7
- *
8
- * By default the hook loads this text from a `blob:` URL. A worklet module is
9
- * loaded as a script, so it is `script-src` that must allow `blob:` —
10
- * `worker-src` does not govern it. Where that is refused, write this string to
11
- * a file your policy's `script-src` does allow, at build time and from the
12
- * installed package so it moves with the version you run, and pass that file's
13
- * URL as `workletUrl`:
14
- *
15
- * ```ts
16
- * import { writeFileSync } from 'node:fs';
17
- * import { CAPTURE_PROCESSOR_SOURCE } from '@intellectif/lk-react/hooks/useSpeechRecorder';
18
- *
19
- * writeFileSync('public/lk-speech-capture.js', CAPTURE_PROCESSOR_SOURCE);
20
- * ```
21
- *
22
- * **The contract** a module at `workletUrl` must meet, which this source does:
23
- * register an `AudioWorkletProcessor` under the name `lk-speech-capture`, and
24
- * from its `process(inputs)` post the first input's channels to its `port` as
25
- * an array with one `Float32Array` per channel, **copied** — the render
26
- * quantum's buffers belong to the audio thread and are overwritten on the next
27
- * quantum, so a block posted without copying arrives as whatever the
28
- * microphone heard some milliseconds later. Return `true`, which keeps the
29
- * processor alive while its source is silent. Anything else changes what is
30
- * recorded, so serve this text unchanged rather than a copy of your own.
31
- */
32
- declare const CAPTURE_PROCESSOR_SOURCE: string;
33
-
34
- interface SpeechRecorderOptions {
35
- /** The longest a take may be. Reached, the recording stops itself. */
36
- maxDurationMs: number;
37
- /** Shorter than this and the take is refused as `too-short`. */
38
- minDurationMs?: number;
39
- /** How many takes the learner may make. Unbounded when absent. */
40
- maxTakes?: number;
41
- /**
42
- * The URL of a self-hosted copy of {@link CAPTURE_PROCESSOR_SOURCE}, for an
43
- * application whose Content-Security-Policy does not allow `blob:` in
44
- * `script-src`. Serve that string unchanged; the contract a module here must
45
- * meet is written on it.
46
- *
47
- * **A URL that does not work is not reported.** If the module fails to load,
48
- * or loads without registering `lk-speech-capture`, the hook records through
49
- * the deprecated `ScriptProcessorNode` on the main thread instead — the
50
- * fallback it keeps for engines without audio worklets — and a recorder with
51
- * a broken `workletUrl` looks like a working one. Only an engine with neither
52
- * path reports `error: 'unsupported'`. Check that the module is actually
53
- * fetched.
54
- */
55
- workletUrl?: string;
56
- }
57
- interface SpeechRecorder {
58
- status: SpeechRecorderStatus;
59
- error: SpeechRecorderError | null;
60
- /** The loudest block since the last update, 0..1. */
61
- level: number;
62
- /** How much audio has been captured, from the sample count. */
63
- elapsedMs: number;
64
- take: RecordedTake | null;
65
- takesUsed: number;
66
- /** Whether a take remains. Not whether a `start()` would be accepted now. */
67
- canRecord: boolean;
68
- /** Opens the microphone and begins capturing. **Never rejects.** */
69
- start(): Promise<void>;
70
- /** Ends the capture and encodes the take. */
71
- stop(): void;
72
- /** Throws the take away and releases the microphone. */
73
- discard(): void;
74
- /**
75
- * Starts over: releases the microphone, throws the take away **and gives the
76
- * budget back**.
77
- *
78
- * That last part is the whole difference from {@link SpeechRecorder.discard},
79
- * which deliberately refunds nothing — a budget a re-record gave back would
80
- * bound nothing. A reset is for a recorder that has been handed a different
81
- * reading while it stayed mounted: the takes belong to the activity, so the
82
- * next activity's are its own. Calling it for the same reading hands a
83
- * learner takes they have already spent.
84
- */
85
- reset(): void;
86
- }
87
- /**
88
- * Records a take of speech as mono 16-bit PCM WAV at 16 kHz.
89
- *
90
- * That is the one format the SDK measures directly: `inspectWav` reads it
91
- * without a decoding library, and it is what every mainstream pronunciation
92
- * assessor accepts. A take is captured at whatever rate the device runs at,
93
- * downmixed to mono, low-pass filtered and resampled, then encoded — so what a
94
- * server measures is what this hook produced, not a claim about it.
95
- *
96
- * **Server rendering.** `status`, `error` and `canRecord` are derived from the
97
- * take count alone and never from a browser global, so the markup a server
98
- * produces is the markup the browser's first render produces. Support is
99
- * discovered inside {@link SpeechRecorder.start} and reported as
100
- * `error: 'unsupported'`; the obvious `!!navigator.mediaDevices` guard at
101
- * render time would make a server render and its hydration disagree.
102
- *
103
- * **Identity.** `start`, `stop`, `discard` and `reset` keep one identity for the
104
- * life of the hook, so they are safe in a dependency array. The returned object keeps
105
- * one identity for as long as none of its values changes, so a render caused
106
- * by something else does not invalidate an effect that depends on it.
107
- *
108
- * `start()` does nothing when no take remains, so `canRecord` is presentation:
109
- * mark the control `aria-disabled` rather than `disabled`, which would take it
110
- * out of the tab order and leave a learner nothing to read.
111
- *
112
- * ```tsx
113
- * const recorder = useSpeechRecorder({ maxDurationMs: 20_000, maxTakes: 3 });
114
- * <button
115
- * type="button"
116
- * aria-disabled={!recorder.canRecord}
117
- * onClick={() => {
118
- * void recorder.start();
119
- * }}
120
- * >
121
- * Record
122
- * </button>
123
- * ```
124
- */
125
- declare function useSpeechRecorder(options: SpeechRecorderOptions): SpeechRecorder;
126
-
127
- export { CAPTURE_PROCESSOR_SOURCE, RecordedTake, type SpeechRecorder, SpeechRecorderError, type SpeechRecorderOptions, SpeechRecorderStatus, useSpeechRecorder };
1
+ import { a as RecordedTake, i as CAPTURE_PROCESSOR_SOURCE, n as SpeechRecorderOptions, o as SpeechRecorderError, r as useSpeechRecorder, s as SpeechRecorderStatus, t as SpeechRecorder } from "../useSpeechRecorder-DtAYvl02.js";
2
+ export { CAPTURE_PROCESSOR_SOURCE, type RecordedTake, SpeechRecorder, type SpeechRecorderError, SpeechRecorderOptions, type SpeechRecorderStatus, useSpeechRecorder };
@@ -1,4 +1,4 @@
1
1
  'use client';
2
- export { CAPTURE_PROCESSOR_SOURCE, useSpeechRecorder } from '../chunk-MCO52PV5.js';
3
- //# sourceMappingURL=useSpeechRecorder.js.map
4
- //# sourceMappingURL=useSpeechRecorder.js.map
2
+ "use client";
3
+ import { n as CAPTURE_PROCESSOR_SOURCE, t as useSpeechRecorder } from "../useSpeechRecorder-zIi9Dlw8.js";
4
+ export { CAPTURE_PROCESSOR_SOURCE, useSpeechRecorder };
@@ -1,13 +1,129 @@
1
1
  'use client';
2
- 'use strict';
2
+ "use client";
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
+ let react = require("react");
5
+ //#region src/hooks/useXAPI.ts
6
+ /** Backoff before retry 1 / 2 / 3. */
7
+ const BACKOFF_MS = [
8
+ 1e3,
9
+ 2e3,
10
+ 4e3
11
+ ];
12
+ /**
13
+ * Applies the configured learner identity to a statement built by an activity
14
+ * component. Components emit an anonymous placeholder actor and a
15
+ * `urn:learning-kit:activity:*` object id (they cannot know identity — Req
16
+ * 3.1); this hook is the documented place where `XAPIConfig.actor` and
17
+ * `XAPIConfig.activityId` take over. Conservative on purpose: the actor is
18
+ * replaced only when the statement still carries the SDK's anonymous
19
+ * placeholder, and the object id only when it is still the SDK URN — a
20
+ * consumer that already rewrote either keeps its own values.
21
+ */
22
+ function applyIdentity(statement, cfg) {
23
+ const isAnonymous = statement.actor?.account?.name === "anonymous" && statement.actor.account.homePage === "https://github.com/intellectif/learning-kit";
24
+ const isSdkObjectId = statement.object?.objectType === "Activity" && typeof statement.object.id === "string" && statement.object.id.startsWith("urn:learning-kit:activity:");
25
+ if (!isAnonymous && !isSdkObjectId) return statement;
26
+ const mappedId = isSdkObjectId && cfg.activityId ? typeof cfg.activityId === "function" ? cfg.activityId(statement.object.id) : cfg.activityId : void 0;
27
+ return {
28
+ ...statement,
29
+ ...isAnonymous && cfg.actor !== void 0 ? { actor: cfg.actor } : {},
30
+ ...mappedId !== void 0 ? { object: {
31
+ ...statement.object,
32
+ id: mappedId
33
+ } } : {}
34
+ };
35
+ }
36
+ /** UTF-8-safe base64 (`btoa` is Latin1-only and breaks on non-ASCII creds). */
37
+ function toBase64Utf8(input) {
38
+ const bytes = new TextEncoder().encode(input);
39
+ let binary = "";
40
+ for (const byte of bytes) binary += String.fromCharCode(byte);
41
+ return btoa(binary);
42
+ }
43
+ function authHeader(auth) {
44
+ return auth.type === "basic" ? `Basic ${toBase64Utf8(`${auth.username}:${auth.password}`)}` : `Bearer ${auth.token}`;
45
+ }
46
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
47
+ /**
48
+ * Delivers xAPI statements to a Learning Record Store, fire-and-forget.
49
+ *
50
+ * Telemetry must never break the learner's attempt, so
51
+ * {@link UseXAPIResult.sendStatement} **never rejects**: network errors and 5xx
52
+ * responses are retried (backoff 1s / 2s / 4s, up to 3 retries), a 4xx fails
53
+ * immediately, and any final failure is reported to `config.onError` instead of
54
+ * throwing. See `XAPIConfig` in `@intellectif/lk-core` for the options.
55
+ *
56
+ * The hook is also where learner identity is applied. Activity components
57
+ * cannot know who the learner is, so they emit an anonymous placeholder actor
58
+ * and a `urn:learning-kit:activity:*` object id; this hook substitutes
59
+ * `config.actor` and `config.activityId` on the way out — and only while those
60
+ * placeholders are still in place, so a statement you rewrote yourself is left
61
+ * alone.
62
+ *
63
+ * `sendStatement` keeps a stable identity across renders even when `config` is
64
+ * an inline object, so it is safe in a dependency array.
65
+ *
66
+ * ```tsx
67
+ * const { sendStatement } = useXAPI({
68
+ * endpoint: 'https://your-lrs.example/xapi/statements',
69
+ * auth: { type: 'bearer', token: 'YOUR_TOKEN' },
70
+ * activityId: 'https://your-app.example/quiz/capital-jp',
71
+ * actor: { objectType: 'Agent', mbox: 'mailto:learner@example.com' },
72
+ * onError: (e) => console.error('xAPI send failed', e),
73
+ * });
74
+ *
75
+ * <MultipleChoice data={quiz} onComplete={(r) => void sendStatement(r.xapiStatement)} />
76
+ * ```
77
+ */
78
+ function useXAPI(config) {
79
+ const configRef = (0, react.useRef)(config);
80
+ configRef.current = config;
81
+ return { sendStatement: (0, react.useCallback)(async (rawStatement) => {
82
+ const cfg = configRef.current;
83
+ const statement = applyIdentity(rawStatement, cfg);
84
+ const maxAttempts = 1 + BACKOFF_MS.length;
85
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
86
+ let statusCode;
87
+ let message = "Request failed";
88
+ try {
89
+ const response = await fetch(cfg.endpoint, {
90
+ method: "POST",
91
+ headers: {
92
+ "Content-Type": "application/json",
93
+ "X-Experience-API-Version": "1.0.3",
94
+ Authorization: authHeader(cfg.auth)
95
+ },
96
+ body: JSON.stringify(statement)
97
+ });
98
+ if (response.ok) return;
99
+ statusCode = response.status;
100
+ message = `LRS responded with ${response.status}`;
101
+ if (response.status < 500) {
102
+ cfg.onError?.({
103
+ statement,
104
+ attempt,
105
+ statusCode,
106
+ message
107
+ });
108
+ return;
109
+ }
110
+ } catch (error) {
111
+ message = error instanceof Error ? error.message : "Network error";
112
+ }
113
+ if (attempt === maxAttempts) {
114
+ cfg.onError?.({
115
+ statement,
116
+ attempt,
117
+ ...statusCode !== void 0 ? { statusCode } : {},
118
+ message
119
+ });
120
+ return;
121
+ }
122
+ await sleep(BACKOFF_MS[attempt - 1]);
123
+ }
124
+ }, []) };
125
+ }
126
+ //#endregion
127
+ exports.useXAPI = useXAPI;
3
128
 
4
- var chunkPNNUPUH4_cjs = require('../chunk-PNNUPUH4.cjs');
5
-
6
-
7
-
8
- Object.defineProperty(exports, "useXAPI", {
9
- enumerable: true,
10
- get: function () { return chunkPNNUPUH4_cjs.useXAPI; }
11
- });
12
- //# sourceMappingURL=useXAPI.cjs.map
13
129
  //# sourceMappingURL=useXAPI.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"useXAPI.cjs"}
1
+ {"version":3,"file":"useXAPI.cjs","names":["useRef","useCallback"],"sources":["../../src/hooks/useXAPI.ts"],"sourcesContent":["'use client';\n\nimport type { XAPIConfig, XAPIStatement } from '@intellectif/lk-core';\nimport { useCallback, useRef } from 'react';\n\n/** Backoff before retry 1 / 2 / 3. */\nconst BACKOFF_MS = [1000, 2000, 4000] as const;\n\n/**\n * Applies the configured learner identity to a statement built by an activity\n * component. Components emit an anonymous placeholder actor and a\n * `urn:learning-kit:activity:*` object id (they cannot know identity — Req\n * 3.1); this hook is the documented place where `XAPIConfig.actor` and\n * `XAPIConfig.activityId` take over. Conservative on purpose: the actor is\n * replaced only when the statement still carries the SDK's anonymous\n * placeholder, and the object id only when it is still the SDK URN — a\n * consumer that already rewrote either keeps its own values.\n */\nfunction applyIdentity(statement: XAPIStatement, cfg: XAPIConfig): XAPIStatement {\n const isAnonymous =\n statement.actor?.account?.name === 'anonymous' &&\n statement.actor.account.homePage === 'https://github.com/intellectif/learning-kit';\n const isSdkObjectId =\n statement.object?.objectType === 'Activity' &&\n typeof statement.object.id === 'string' &&\n statement.object.id.startsWith('urn:learning-kit:activity:');\n\n if (!isAnonymous && !isSdkObjectId) {\n return statement;\n }\n const mappedId =\n isSdkObjectId && cfg.activityId\n ? typeof cfg.activityId === 'function'\n ? cfg.activityId(statement.object.id)\n : cfg.activityId\n : undefined;\n return {\n ...statement,\n ...(isAnonymous && cfg.actor !== undefined ? { actor: cfg.actor } : {}),\n ...(mappedId !== undefined ? { object: { ...statement.object, id: mappedId } } : {}),\n };\n}\n\n/** UTF-8-safe base64 (`btoa` is Latin1-only and breaks on non-ASCII creds). */\nfunction toBase64Utf8(input: string): string {\n const bytes = new TextEncoder().encode(input);\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nfunction authHeader(auth: XAPIConfig['auth']): string {\n return auth.type === 'basic'\n ? `Basic ${toBase64Utf8(`${auth.username}:${auth.password}`)}`\n : `Bearer ${auth.token}`;\n}\n\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport interface UseXAPIResult {\n /**\n * Sends a statement to the configured LRS. **Never rejects** — xAPI is\n * fire-and-forget telemetry that must not break the learner's activity\n * flow. Network errors and 5xx responses are retried (backoff 1s/2s/4s,\n * up to 3 retries); a 4xx fails immediately. Any final failure is delivered\n * to `config.onError`.\n */\n sendStatement: (statement: XAPIStatement) => Promise<void>;\n}\n\n/**\n * Delivers xAPI statements to a Learning Record Store, fire-and-forget.\n *\n * Telemetry must never break the learner's attempt, so\n * {@link UseXAPIResult.sendStatement} **never rejects**: network errors and 5xx\n * responses are retried (backoff 1s / 2s / 4s, up to 3 retries), a 4xx fails\n * immediately, and any final failure is reported to `config.onError` instead of\n * throwing. See `XAPIConfig` in `@intellectif/lk-core` for the options.\n *\n * The hook is also where learner identity is applied. Activity components\n * cannot know who the learner is, so they emit an anonymous placeholder actor\n * and a `urn:learning-kit:activity:*` object id; this hook substitutes\n * `config.actor` and `config.activityId` on the way out — and only while those\n * placeholders are still in place, so a statement you rewrote yourself is left\n * alone.\n *\n * `sendStatement` keeps a stable identity across renders even when `config` is\n * an inline object, so it is safe in a dependency array.\n *\n * ```tsx\n * const { sendStatement } = useXAPI({\n * endpoint: 'https://your-lrs.example/xapi/statements',\n * auth: { type: 'bearer', token: 'YOUR_TOKEN' },\n * activityId: 'https://your-app.example/quiz/capital-jp',\n * actor: { objectType: 'Agent', mbox: 'mailto:learner@example.com' },\n * onError: (e) => console.error('xAPI send failed', e),\n * });\n *\n * <MultipleChoice data={quiz} onComplete={(r) => void sendStatement(r.xapiStatement)} />\n * ```\n */\nexport function useXAPI(config: XAPIConfig): UseXAPIResult {\n // Keep the latest config without changing `sendStatement`'s identity when\n // callers pass an inline config object.\n const configRef = useRef(config);\n configRef.current = config;\n\n const sendStatement = useCallback(async (rawStatement: XAPIStatement): Promise<void> => {\n const cfg = configRef.current;\n const statement = applyIdentity(rawStatement, cfg);\n const maxAttempts = 1 + BACKOFF_MS.length;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n let statusCode: number | undefined;\n let message = 'Request failed';\n\n try {\n const response = await fetch(cfg.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Experience-API-Version': '1.0.3',\n Authorization: authHeader(cfg.auth),\n },\n body: JSON.stringify(statement),\n });\n\n if (response.ok) {\n return;\n }\n\n statusCode = response.status;\n message = `LRS responded with ${response.status}`;\n\n // Only network errors and 5xx are retryable. A 4xx is a\n // client error — fail immediately rather than waste retries.\n if (response.status < 500) {\n cfg.onError?.({ statement, attempt, statusCode, message });\n return;\n }\n } catch (error) {\n message = error instanceof Error ? error.message : 'Network error';\n }\n\n if (attempt === maxAttempts) {\n cfg.onError?.({\n statement,\n attempt,\n ...(statusCode !== undefined ? { statusCode } : {}),\n message,\n });\n return;\n }\n\n await sleep(BACKOFF_MS[attempt - 1]);\n }\n }, []);\n\n return { sendStatement };\n}\n"],"mappings":";;;;;AAMA,MAAM,aAAa;CAAC;CAAM;CAAM;AAAI;;;;;;;;;;;AAYpC,SAAS,cAAc,WAA0B,KAAgC;CAC/E,MAAM,cACJ,UAAU,OAAO,SAAS,SAAS,eACnC,UAAU,MAAM,QAAQ,aAAa;CACvC,MAAM,gBACJ,UAAU,QAAQ,eAAe,cACjC,OAAO,UAAU,OAAO,OAAO,YAC/B,UAAU,OAAO,GAAG,WAAW,4BAA4B;CAE7D,IAAI,CAAC,eAAe,CAAC,eACnB,OAAO;CAET,MAAM,WACJ,iBAAiB,IAAI,aACjB,OAAO,IAAI,eAAe,aACxB,IAAI,WAAW,UAAU,OAAO,EAAE,IAClC,IAAI,aACN,KAAA;CACN,OAAO;EACL,GAAG;EACH,GAAI,eAAe,IAAI,UAAU,KAAA,IAAY,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;EACrE,GAAI,aAAa,KAAA,IAAY,EAAE,QAAQ;GAAE,GAAG,UAAU;GAAQ,IAAI;EAAS,EAAE,IAAI,CAAC;CACpF;AACF;;AAGA,SAAS,aAAa,OAAuB;CAC3C,MAAM,QAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;CAC5C,IAAI,SAAS;CACb,KAAK,MAAM,QAAQ,OACjB,UAAU,OAAO,aAAa,IAAI;CAEpC,OAAO,KAAK,MAAM;AACpB;AAEA,SAAS,WAAW,MAAkC;CACpD,OAAO,KAAK,SAAS,UACjB,SAAS,aAAa,GAAG,KAAK,SAAS,GAAG,KAAK,UAAU,MACzD,UAAU,KAAK;AACrB;AAEA,MAAM,SAAS,OAA8B,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4C7F,SAAgB,QAAQ,QAAmC;CAGzD,MAAM,aAAA,GAAYA,MAAAA,OAAAA,CAAO,MAAM;CAC/B,UAAU,UAAU;CAqDpB,OAAO,EAAE,gBAAA,GAnDaC,MAAAA,YAAAA,CAAY,OAAO,iBAA+C;EACtF,MAAM,MAAM,UAAU;EACtB,MAAM,YAAY,cAAc,cAAc,GAAG;EACjD,MAAM,cAAc,IAAI,WAAW;EAEnC,KAAK,IAAI,UAAU,GAAG,WAAW,aAAa,WAAW,GAAG;GAC1D,IAAI;GACJ,IAAI,UAAU;GAEd,IAAI;IACF,MAAM,WAAW,MAAM,MAAM,IAAI,UAAU;KACzC,QAAQ;KACR,SAAS;MACP,gBAAgB;MAChB,4BAA4B;MAC5B,eAAe,WAAW,IAAI,IAAI;KACpC;KACA,MAAM,KAAK,UAAU,SAAS;IAChC,CAAC;IAED,IAAI,SAAS,IACX;IAGF,aAAa,SAAS;IACtB,UAAU,sBAAsB,SAAS;IAIzC,IAAI,SAAS,SAAS,KAAK;KACzB,IAAI,UAAU;MAAE;MAAW;MAAS;MAAY;KAAQ,CAAC;KACzD;IACF;GACF,SAAS,OAAO;IACd,UAAU,iBAAiB,QAAQ,MAAM,UAAU;GACrD;GAEA,IAAI,YAAY,aAAa;IAC3B,IAAI,UAAU;KACZ;KACA;KACA,GAAI,eAAe,KAAA,IAAY,EAAE,WAAW,IAAI,CAAC;KACjD;IACF,CAAC;IACD;GACF;GAEA,MAAM,MAAM,WAAW,UAAU,EAAE;EACrC;CACF,GAAG,CAAC,CAEiB,EAAE;AACzB"}
@@ -1,14 +1,14 @@
1
- import { XAPIStatement, XAPIConfig } from '@intellectif/lk-core';
2
-
3
- interface UseXAPIResult {
4
- /**
5
- * Sends a statement to the configured LRS. **Never rejects** — xAPI is
6
- * fire-and-forget telemetry that must not break the learner's activity
7
- * flow. Network errors and 5xx responses are retried (backoff 1s/2s/4s,
8
- * up to 3 retries); a 4xx fails immediately. Any final failure is delivered
9
- * to `config.onError`.
10
- */
11
- sendStatement: (statement: XAPIStatement) => Promise<void>;
1
+ import { XAPIConfig, XAPIStatement } from "@intellectif/lk-core";
2
+ //#region src/hooks/useXAPI.d.ts
3
+ export interface UseXAPIResult {
4
+ /**
5
+ * Sends a statement to the configured LRS. **Never rejects** — xAPI is
6
+ * fire-and-forget telemetry that must not break the learner's activity
7
+ * flow. Network errors and 5xx responses are retried (backoff 1s/2s/4s,
8
+ * up to 3 retries); a 4xx fails immediately. Any final failure is delivered
9
+ * to `config.onError`.
10
+ */
11
+ sendStatement: (statement: XAPIStatement) => Promise<void>;
12
12
  }
13
13
  /**
14
14
  * Delivers xAPI statements to a Learning Record Store, fire-and-forget.
@@ -41,6 +41,6 @@ interface UseXAPIResult {
41
41
  * <MultipleChoice data={quiz} onComplete={(r) => void sendStatement(r.xapiStatement)} />
42
42
  * ```
43
43
  */
44
- declare function useXAPI(config: XAPIConfig): UseXAPIResult;
45
-
46
- export { type UseXAPIResult, useXAPI };
44
+ export declare function useXAPI(config: XAPIConfig): UseXAPIResult;
45
+ //#endregion
46
+ //# sourceMappingURL=useXAPI.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useXAPI.d.cts","names":[],"sources":["../../src/hooks/useXAPI.ts"],"mappings":";;iBA6DiB;;;;;;;;EAQf,gBAAgB,WAAW,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAkC/B,QAAQ,QAAQ,aAAa"}
@@ -1,14 +1,14 @@
1
- import { XAPIStatement, XAPIConfig } from '@intellectif/lk-core';
2
-
3
- interface UseXAPIResult {
4
- /**
5
- * Sends a statement to the configured LRS. **Never rejects** — xAPI is
6
- * fire-and-forget telemetry that must not break the learner's activity
7
- * flow. Network errors and 5xx responses are retried (backoff 1s/2s/4s,
8
- * up to 3 retries); a 4xx fails immediately. Any final failure is delivered
9
- * to `config.onError`.
10
- */
11
- sendStatement: (statement: XAPIStatement) => Promise<void>;
1
+ import { XAPIConfig, XAPIStatement } from "@intellectif/lk-core";
2
+ //#region src/hooks/useXAPI.d.ts
3
+ export interface UseXAPIResult {
4
+ /**
5
+ * Sends a statement to the configured LRS. **Never rejects** — xAPI is
6
+ * fire-and-forget telemetry that must not break the learner's activity
7
+ * flow. Network errors and 5xx responses are retried (backoff 1s/2s/4s,
8
+ * up to 3 retries); a 4xx fails immediately. Any final failure is delivered
9
+ * to `config.onError`.
10
+ */
11
+ sendStatement: (statement: XAPIStatement) => Promise<void>;
12
12
  }
13
13
  /**
14
14
  * Delivers xAPI statements to a Learning Record Store, fire-and-forget.
@@ -41,6 +41,6 @@ interface UseXAPIResult {
41
41
  * <MultipleChoice data={quiz} onComplete={(r) => void sendStatement(r.xapiStatement)} />
42
42
  * ```
43
43
  */
44
- declare function useXAPI(config: XAPIConfig): UseXAPIResult;
45
-
46
- export { type UseXAPIResult, useXAPI };
44
+ export declare function useXAPI(config: XAPIConfig): UseXAPIResult;
45
+ //#endregion
46
+ //# sourceMappingURL=useXAPI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useXAPI.d.ts","names":[],"sources":["../../src/hooks/useXAPI.ts"],"mappings":";;iBA6DiB;;;;;;;;EAQf,gBAAgB,WAAW,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAkC/B,QAAQ,QAAQ,aAAa"}
@@ -1,4 +1,128 @@
1
1
  'use client';
2
- export { useXAPI } from '../chunk-2TW6WLBC.js';
3
- //# sourceMappingURL=useXAPI.js.map
2
+ "use client";
3
+ import { useCallback, useRef } from "react";
4
+ //#region src/hooks/useXAPI.ts
5
+ /** Backoff before retry 1 / 2 / 3. */
6
+ const BACKOFF_MS = [
7
+ 1e3,
8
+ 2e3,
9
+ 4e3
10
+ ];
11
+ /**
12
+ * Applies the configured learner identity to a statement built by an activity
13
+ * component. Components emit an anonymous placeholder actor and a
14
+ * `urn:learning-kit:activity:*` object id (they cannot know identity — Req
15
+ * 3.1); this hook is the documented place where `XAPIConfig.actor` and
16
+ * `XAPIConfig.activityId` take over. Conservative on purpose: the actor is
17
+ * replaced only when the statement still carries the SDK's anonymous
18
+ * placeholder, and the object id only when it is still the SDK URN — a
19
+ * consumer that already rewrote either keeps its own values.
20
+ */
21
+ function applyIdentity(statement, cfg) {
22
+ const isAnonymous = statement.actor?.account?.name === "anonymous" && statement.actor.account.homePage === "https://github.com/intellectif/learning-kit";
23
+ const isSdkObjectId = statement.object?.objectType === "Activity" && typeof statement.object.id === "string" && statement.object.id.startsWith("urn:learning-kit:activity:");
24
+ if (!isAnonymous && !isSdkObjectId) return statement;
25
+ const mappedId = isSdkObjectId && cfg.activityId ? typeof cfg.activityId === "function" ? cfg.activityId(statement.object.id) : cfg.activityId : void 0;
26
+ return {
27
+ ...statement,
28
+ ...isAnonymous && cfg.actor !== void 0 ? { actor: cfg.actor } : {},
29
+ ...mappedId !== void 0 ? { object: {
30
+ ...statement.object,
31
+ id: mappedId
32
+ } } : {}
33
+ };
34
+ }
35
+ /** UTF-8-safe base64 (`btoa` is Latin1-only and breaks on non-ASCII creds). */
36
+ function toBase64Utf8(input) {
37
+ const bytes = new TextEncoder().encode(input);
38
+ let binary = "";
39
+ for (const byte of bytes) binary += String.fromCharCode(byte);
40
+ return btoa(binary);
41
+ }
42
+ function authHeader(auth) {
43
+ return auth.type === "basic" ? `Basic ${toBase64Utf8(`${auth.username}:${auth.password}`)}` : `Bearer ${auth.token}`;
44
+ }
45
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
46
+ /**
47
+ * Delivers xAPI statements to a Learning Record Store, fire-and-forget.
48
+ *
49
+ * Telemetry must never break the learner's attempt, so
50
+ * {@link UseXAPIResult.sendStatement} **never rejects**: network errors and 5xx
51
+ * responses are retried (backoff 1s / 2s / 4s, up to 3 retries), a 4xx fails
52
+ * immediately, and any final failure is reported to `config.onError` instead of
53
+ * throwing. See `XAPIConfig` in `@intellectif/lk-core` for the options.
54
+ *
55
+ * The hook is also where learner identity is applied. Activity components
56
+ * cannot know who the learner is, so they emit an anonymous placeholder actor
57
+ * and a `urn:learning-kit:activity:*` object id; this hook substitutes
58
+ * `config.actor` and `config.activityId` on the way out — and only while those
59
+ * placeholders are still in place, so a statement you rewrote yourself is left
60
+ * alone.
61
+ *
62
+ * `sendStatement` keeps a stable identity across renders even when `config` is
63
+ * an inline object, so it is safe in a dependency array.
64
+ *
65
+ * ```tsx
66
+ * const { sendStatement } = useXAPI({
67
+ * endpoint: 'https://your-lrs.example/xapi/statements',
68
+ * auth: { type: 'bearer', token: 'YOUR_TOKEN' },
69
+ * activityId: 'https://your-app.example/quiz/capital-jp',
70
+ * actor: { objectType: 'Agent', mbox: 'mailto:learner@example.com' },
71
+ * onError: (e) => console.error('xAPI send failed', e),
72
+ * });
73
+ *
74
+ * <MultipleChoice data={quiz} onComplete={(r) => void sendStatement(r.xapiStatement)} />
75
+ * ```
76
+ */
77
+ function useXAPI(config) {
78
+ const configRef = useRef(config);
79
+ configRef.current = config;
80
+ return { sendStatement: useCallback(async (rawStatement) => {
81
+ const cfg = configRef.current;
82
+ const statement = applyIdentity(rawStatement, cfg);
83
+ const maxAttempts = 1 + BACKOFF_MS.length;
84
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
85
+ let statusCode;
86
+ let message = "Request failed";
87
+ try {
88
+ const response = await fetch(cfg.endpoint, {
89
+ method: "POST",
90
+ headers: {
91
+ "Content-Type": "application/json",
92
+ "X-Experience-API-Version": "1.0.3",
93
+ Authorization: authHeader(cfg.auth)
94
+ },
95
+ body: JSON.stringify(statement)
96
+ });
97
+ if (response.ok) return;
98
+ statusCode = response.status;
99
+ message = `LRS responded with ${response.status}`;
100
+ if (response.status < 500) {
101
+ cfg.onError?.({
102
+ statement,
103
+ attempt,
104
+ statusCode,
105
+ message
106
+ });
107
+ return;
108
+ }
109
+ } catch (error) {
110
+ message = error instanceof Error ? error.message : "Network error";
111
+ }
112
+ if (attempt === maxAttempts) {
113
+ cfg.onError?.({
114
+ statement,
115
+ attempt,
116
+ ...statusCode !== void 0 ? { statusCode } : {},
117
+ message
118
+ });
119
+ return;
120
+ }
121
+ await sleep(BACKOFF_MS[attempt - 1]);
122
+ }
123
+ }, []) };
124
+ }
125
+ //#endregion
126
+ export { useXAPI };
127
+
4
128
  //# sourceMappingURL=useXAPI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"useXAPI.js"}
1
+ {"version":3,"file":"useXAPI.js","names":[],"sources":["../../src/hooks/useXAPI.ts"],"sourcesContent":["'use client';\n\nimport type { XAPIConfig, XAPIStatement } from '@intellectif/lk-core';\nimport { useCallback, useRef } from 'react';\n\n/** Backoff before retry 1 / 2 / 3. */\nconst BACKOFF_MS = [1000, 2000, 4000] as const;\n\n/**\n * Applies the configured learner identity to a statement built by an activity\n * component. Components emit an anonymous placeholder actor and a\n * `urn:learning-kit:activity:*` object id (they cannot know identity — Req\n * 3.1); this hook is the documented place where `XAPIConfig.actor` and\n * `XAPIConfig.activityId` take over. Conservative on purpose: the actor is\n * replaced only when the statement still carries the SDK's anonymous\n * placeholder, and the object id only when it is still the SDK URN — a\n * consumer that already rewrote either keeps its own values.\n */\nfunction applyIdentity(statement: XAPIStatement, cfg: XAPIConfig): XAPIStatement {\n const isAnonymous =\n statement.actor?.account?.name === 'anonymous' &&\n statement.actor.account.homePage === 'https://github.com/intellectif/learning-kit';\n const isSdkObjectId =\n statement.object?.objectType === 'Activity' &&\n typeof statement.object.id === 'string' &&\n statement.object.id.startsWith('urn:learning-kit:activity:');\n\n if (!isAnonymous && !isSdkObjectId) {\n return statement;\n }\n const mappedId =\n isSdkObjectId && cfg.activityId\n ? typeof cfg.activityId === 'function'\n ? cfg.activityId(statement.object.id)\n : cfg.activityId\n : undefined;\n return {\n ...statement,\n ...(isAnonymous && cfg.actor !== undefined ? { actor: cfg.actor } : {}),\n ...(mappedId !== undefined ? { object: { ...statement.object, id: mappedId } } : {}),\n };\n}\n\n/** UTF-8-safe base64 (`btoa` is Latin1-only and breaks on non-ASCII creds). */\nfunction toBase64Utf8(input: string): string {\n const bytes = new TextEncoder().encode(input);\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nfunction authHeader(auth: XAPIConfig['auth']): string {\n return auth.type === 'basic'\n ? `Basic ${toBase64Utf8(`${auth.username}:${auth.password}`)}`\n : `Bearer ${auth.token}`;\n}\n\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport interface UseXAPIResult {\n /**\n * Sends a statement to the configured LRS. **Never rejects** — xAPI is\n * fire-and-forget telemetry that must not break the learner's activity\n * flow. Network errors and 5xx responses are retried (backoff 1s/2s/4s,\n * up to 3 retries); a 4xx fails immediately. Any final failure is delivered\n * to `config.onError`.\n */\n sendStatement: (statement: XAPIStatement) => Promise<void>;\n}\n\n/**\n * Delivers xAPI statements to a Learning Record Store, fire-and-forget.\n *\n * Telemetry must never break the learner's attempt, so\n * {@link UseXAPIResult.sendStatement} **never rejects**: network errors and 5xx\n * responses are retried (backoff 1s / 2s / 4s, up to 3 retries), a 4xx fails\n * immediately, and any final failure is reported to `config.onError` instead of\n * throwing. See `XAPIConfig` in `@intellectif/lk-core` for the options.\n *\n * The hook is also where learner identity is applied. Activity components\n * cannot know who the learner is, so they emit an anonymous placeholder actor\n * and a `urn:learning-kit:activity:*` object id; this hook substitutes\n * `config.actor` and `config.activityId` on the way out — and only while those\n * placeholders are still in place, so a statement you rewrote yourself is left\n * alone.\n *\n * `sendStatement` keeps a stable identity across renders even when `config` is\n * an inline object, so it is safe in a dependency array.\n *\n * ```tsx\n * const { sendStatement } = useXAPI({\n * endpoint: 'https://your-lrs.example/xapi/statements',\n * auth: { type: 'bearer', token: 'YOUR_TOKEN' },\n * activityId: 'https://your-app.example/quiz/capital-jp',\n * actor: { objectType: 'Agent', mbox: 'mailto:learner@example.com' },\n * onError: (e) => console.error('xAPI send failed', e),\n * });\n *\n * <MultipleChoice data={quiz} onComplete={(r) => void sendStatement(r.xapiStatement)} />\n * ```\n */\nexport function useXAPI(config: XAPIConfig): UseXAPIResult {\n // Keep the latest config without changing `sendStatement`'s identity when\n // callers pass an inline config object.\n const configRef = useRef(config);\n configRef.current = config;\n\n const sendStatement = useCallback(async (rawStatement: XAPIStatement): Promise<void> => {\n const cfg = configRef.current;\n const statement = applyIdentity(rawStatement, cfg);\n const maxAttempts = 1 + BACKOFF_MS.length;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n let statusCode: number | undefined;\n let message = 'Request failed';\n\n try {\n const response = await fetch(cfg.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Experience-API-Version': '1.0.3',\n Authorization: authHeader(cfg.auth),\n },\n body: JSON.stringify(statement),\n });\n\n if (response.ok) {\n return;\n }\n\n statusCode = response.status;\n message = `LRS responded with ${response.status}`;\n\n // Only network errors and 5xx are retryable. A 4xx is a\n // client error — fail immediately rather than waste retries.\n if (response.status < 500) {\n cfg.onError?.({ statement, attempt, statusCode, message });\n return;\n }\n } catch (error) {\n message = error instanceof Error ? error.message : 'Network error';\n }\n\n if (attempt === maxAttempts) {\n cfg.onError?.({\n statement,\n attempt,\n ...(statusCode !== undefined ? { statusCode } : {}),\n message,\n });\n return;\n }\n\n await sleep(BACKOFF_MS[attempt - 1]);\n }\n }, []);\n\n return { sendStatement };\n}\n"],"mappings":";;;;AAMA,MAAM,aAAa;CAAC;CAAM;CAAM;AAAI;;;;;;;;;;;AAYpC,SAAS,cAAc,WAA0B,KAAgC;CAC/E,MAAM,cACJ,UAAU,OAAO,SAAS,SAAS,eACnC,UAAU,MAAM,QAAQ,aAAa;CACvC,MAAM,gBACJ,UAAU,QAAQ,eAAe,cACjC,OAAO,UAAU,OAAO,OAAO,YAC/B,UAAU,OAAO,GAAG,WAAW,4BAA4B;CAE7D,IAAI,CAAC,eAAe,CAAC,eACnB,OAAO;CAET,MAAM,WACJ,iBAAiB,IAAI,aACjB,OAAO,IAAI,eAAe,aACxB,IAAI,WAAW,UAAU,OAAO,EAAE,IAClC,IAAI,aACN,KAAA;CACN,OAAO;EACL,GAAG;EACH,GAAI,eAAe,IAAI,UAAU,KAAA,IAAY,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;EACrE,GAAI,aAAa,KAAA,IAAY,EAAE,QAAQ;GAAE,GAAG,UAAU;GAAQ,IAAI;EAAS,EAAE,IAAI,CAAC;CACpF;AACF;;AAGA,SAAS,aAAa,OAAuB;CAC3C,MAAM,QAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;CAC5C,IAAI,SAAS;CACb,KAAK,MAAM,QAAQ,OACjB,UAAU,OAAO,aAAa,IAAI;CAEpC,OAAO,KAAK,MAAM;AACpB;AAEA,SAAS,WAAW,MAAkC;CACpD,OAAO,KAAK,SAAS,UACjB,SAAS,aAAa,GAAG,KAAK,SAAS,GAAG,KAAK,UAAU,MACzD,UAAU,KAAK;AACrB;AAEA,MAAM,SAAS,OAA8B,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4C7F,SAAgB,QAAQ,QAAmC;CAGzD,MAAM,YAAY,OAAO,MAAM;CAC/B,UAAU,UAAU;CAqDpB,OAAO,EAAE,eAnDa,YAAY,OAAO,iBAA+C;EACtF,MAAM,MAAM,UAAU;EACtB,MAAM,YAAY,cAAc,cAAc,GAAG;EACjD,MAAM,cAAc,IAAI,WAAW;EAEnC,KAAK,IAAI,UAAU,GAAG,WAAW,aAAa,WAAW,GAAG;GAC1D,IAAI;GACJ,IAAI,UAAU;GAEd,IAAI;IACF,MAAM,WAAW,MAAM,MAAM,IAAI,UAAU;KACzC,QAAQ;KACR,SAAS;MACP,gBAAgB;MAChB,4BAA4B;MAC5B,eAAe,WAAW,IAAI,IAAI;KACpC;KACA,MAAM,KAAK,UAAU,SAAS;IAChC,CAAC;IAED,IAAI,SAAS,IACX;IAGF,aAAa,SAAS;IACtB,UAAU,sBAAsB,SAAS;IAIzC,IAAI,SAAS,SAAS,KAAK;KACzB,IAAI,UAAU;MAAE;MAAW;MAAS;MAAY;KAAQ,CAAC;KACzD;IACF;GACF,SAAS,OAAO;IACd,UAAU,iBAAiB,QAAQ,MAAM,UAAU;GACrD;GAEA,IAAI,YAAY,aAAa;IAC3B,IAAI,UAAU;KACZ;KACA;KACA,GAAI,eAAe,KAAA,IAAY,EAAE,WAAW,IAAI,CAAC;KACjD;IACF,CAAC;IACD;GACF;GAEA,MAAM,MAAM,WAAW,UAAU,EAAE;EACrC;CACF,GAAG,CAAC,CAEiB,EAAE;AACzB"}
@@ -1,33 +1,10 @@
1
1
  'use client';
2
- 'use strict';
3
-
4
- var chunkBIGGXHAW_cjs = require('../chunk-BIGGXHAW.cjs');
5
-
6
-
7
-
8
- Object.defineProperty(exports, "DEFAULT_STRINGS", {
9
- enumerable: true,
10
- get: function () { return chunkBIGGXHAW_cjs.DEFAULT_STRINGS; }
11
- });
12
- Object.defineProperty(exports, "LkIntlProvider", {
13
- enumerable: true,
14
- get: function () { return chunkBIGGXHAW_cjs.LkIntlProvider; }
15
- });
16
- Object.defineProperty(exports, "directionForLocale", {
17
- enumerable: true,
18
- get: function () { return chunkBIGGXHAW_cjs.directionForLocale; }
19
- });
20
- Object.defineProperty(exports, "mergeStrings", {
21
- enumerable: true,
22
- get: function () { return chunkBIGGXHAW_cjs.mergeStrings; }
23
- });
24
- Object.defineProperty(exports, "useLkDirection", {
25
- enumerable: true,
26
- get: function () { return chunkBIGGXHAW_cjs.useLkDirection; }
27
- });
28
- Object.defineProperty(exports, "useLkStrings", {
29
- enumerable: true,
30
- get: function () { return chunkBIGGXHAW_cjs.useLkStrings; }
31
- });
32
- //# sourceMappingURL=LkIntlProvider.cjs.map
33
- //# sourceMappingURL=LkIntlProvider.cjs.map
2
+ "use client";
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
+ const require_LkIntlProvider = require("../LkIntlProvider-oi57lYB0.cjs");
5
+ exports.DEFAULT_STRINGS = require_LkIntlProvider.DEFAULT_STRINGS;
6
+ exports.LkIntlProvider = require_LkIntlProvider.LkIntlProvider;
7
+ exports.directionForLocale = require_LkIntlProvider.directionForLocale;
8
+ exports.mergeStrings = require_LkIntlProvider.mergeStrings;
9
+ exports.useLkDirection = require_LkIntlProvider.useLkDirection;
10
+ exports.useLkStrings = require_LkIntlProvider.useLkStrings;