@intellectif/lk-react 13.0.0 → 14.1.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.
- package/CHANGELOG.md +61 -0
- package/README.md +11 -3
- package/dist/{WrittenResponse-B5p_-RnJ.d.ts → WrittenResponse-DrzI89Wg.d.ts} +1 -1
- package/dist/{WrittenResponse-DWtS4tOL.d.cts → WrittenResponse-rRpOr9W1.d.cts} +1 -1
- package/dist/{chunk-UU2NV6SU.cjs → chunk-4Y5TELVU.cjs} +14 -13
- package/dist/chunk-4Y5TELVU.cjs.map +1 -0
- package/dist/{chunk-XAGWBVK3.js → chunk-5CP2Z6IS.js} +6 -5
- package/dist/chunk-5CP2Z6IS.js.map +1 -0
- package/dist/{chunk-NVUFEMPZ.cjs → chunk-5JCTJFQU.cjs} +30 -16
- package/dist/chunk-5JCTJFQU.cjs.map +1 -0
- package/dist/chunk-5JFMXBH7.js +888 -0
- package/dist/chunk-5JFMXBH7.js.map +1 -0
- package/dist/{chunk-NVP6UEQQ.js → chunk-AS2QGND5.js} +4 -4
- package/dist/{chunk-NVP6UEQQ.js.map → chunk-AS2QGND5.js.map} +1 -1
- package/dist/{chunk-3Q4I4KT6.js → chunk-AWQ53DON.js} +78 -2
- package/dist/chunk-AWQ53DON.js.map +1 -0
- package/dist/{chunk-DQERNAWI.js → chunk-B4BCEQNO.js} +26 -31
- package/dist/chunk-B4BCEQNO.js.map +1 -0
- package/dist/chunk-BRPEB43C.cjs +13 -0
- package/dist/chunk-BRPEB43C.cjs.map +1 -0
- package/dist/{chunk-74QXBWCI.cjs → chunk-CTW3G3EH.cjs} +6 -6
- package/dist/{chunk-74QXBWCI.cjs.map → chunk-CTW3G3EH.cjs.map} +1 -1
- package/dist/{chunk-AMGK7DDM.cjs → chunk-D4DQFTA7.cjs} +2 -2
- package/dist/chunk-D4DQFTA7.cjs.map +1 -0
- package/dist/{chunk-R7DI5UMU.js → chunk-DB4DLHN6.js} +22 -4
- package/dist/chunk-DB4DLHN6.js.map +1 -0
- package/dist/{chunk-K3EA547J.cjs → chunk-DPEY7DSE.cjs} +27 -33
- package/dist/chunk-DPEY7DSE.cjs.map +1 -0
- package/dist/{chunk-W4MXRZAB.js → chunk-IDYZ2FA2.js} +6 -5
- package/dist/chunk-IDYZ2FA2.js.map +1 -0
- package/dist/{chunk-K7NMNOPI.cjs → chunk-JG4DWAUJ.cjs} +15 -14
- package/dist/chunk-JG4DWAUJ.cjs.map +1 -0
- package/dist/chunk-KIO6QXGT.cjs +894 -0
- package/dist/chunk-KIO6QXGT.cjs.map +1 -0
- package/dist/chunk-MCO52PV5.js +520 -0
- package/dist/chunk-MCO52PV5.js.map +1 -0
- package/dist/{chunk-HT4FFZZQ.cjs → chunk-MZITNWZ2.cjs} +233 -38
- package/dist/chunk-MZITNWZ2.cjs.map +1 -0
- package/dist/{chunk-Z63JRG4M.cjs → chunk-N536RUCZ.cjs} +15 -14
- package/dist/chunk-N536RUCZ.cjs.map +1 -0
- package/dist/{chunk-PSHNTDKG.js → chunk-NJAF34GN.js} +13 -161
- package/dist/chunk-NJAF34GN.js.map +1 -0
- package/dist/chunk-OD65OZIW.cjs +159 -0
- package/dist/chunk-OD65OZIW.cjs.map +1 -0
- package/dist/{chunk-2GXSA322.cjs → chunk-PSUKWVKU.cjs} +15 -14
- package/dist/chunk-PSUKWVKU.cjs.map +1 -0
- package/dist/chunk-RCMYEWBE.js +11 -0
- package/dist/chunk-RCMYEWBE.js.map +1 -0
- package/dist/{chunk-PY53ABWC.js → chunk-RCPW6HVY.js} +23 -9
- package/dist/chunk-RCPW6HVY.js.map +1 -0
- package/dist/{chunk-DQNVAXG6.js → chunk-RXS455MR.js} +2 -2
- package/dist/chunk-RXS455MR.js.map +1 -0
- package/dist/chunk-TUVEJLOT.js +537 -0
- package/dist/chunk-TUVEJLOT.js.map +1 -0
- package/dist/{chunk-YZWXVZB3.js → chunk-U432HTUW.js} +6 -5
- package/dist/chunk-U432HTUW.js.map +1 -0
- package/dist/chunk-UDCQTOVU.cjs +523 -0
- package/dist/chunk-UDCQTOVU.cjs.map +1 -0
- package/dist/{chunk-5N7OLFHB.js → chunk-UDQS5INQ.js} +6 -5
- package/dist/chunk-UDQS5INQ.js.map +1 -0
- package/dist/{chunk-YILH4ETT.js → chunk-UDZWYHDV.js} +226 -31
- package/dist/chunk-UDZWYHDV.js.map +1 -0
- package/dist/{chunk-SBIJJ374.cjs → chunk-UMDWVMB5.cjs} +24 -6
- package/dist/chunk-UMDWVMB5.cjs.map +1 -0
- package/dist/{chunk-MA7GXUWC.cjs → chunk-VSFHJ7FB.cjs} +78 -2
- package/dist/chunk-VSFHJ7FB.cjs.map +1 -0
- package/dist/{chunk-J73TDY7J.cjs → chunk-WC4OD3EE.cjs} +25 -173
- package/dist/chunk-WC4OD3EE.cjs.map +1 -0
- package/dist/chunk-YM64MS4G.cjs +547 -0
- package/dist/chunk-YM64MS4G.cjs.map +1 -0
- package/dist/chunk-YORQQXGO.js +155 -0
- package/dist/chunk-YORQQXGO.js.map +1 -0
- package/dist/components/ActivityPreview.cjs +15 -10
- package/dist/components/ActivityPreview.d.cts +9 -3
- package/dist/components/ActivityPreview.d.ts +9 -3
- package/dist/components/ActivityPreview.js +14 -9
- package/dist/components/ActivitySequence.cjs +16 -11
- package/dist/components/ActivitySequence.d.cts +115 -4
- package/dist/components/ActivitySequence.d.ts +115 -4
- package/dist/components/ActivitySequence.js +15 -10
- package/dist/components/Dictation.cjs +7 -5
- package/dist/components/Dictation.d.cts +2 -1
- package/dist/components/Dictation.d.ts +2 -1
- package/dist/components/Dictation.js +6 -4
- package/dist/components/FillInTheBlanks.cjs +6 -5
- package/dist/components/FillInTheBlanks.d.cts +2 -1
- package/dist/components/FillInTheBlanks.d.ts +2 -1
- package/dist/components/FillInTheBlanks.js +5 -4
- package/dist/components/GapSelect.cjs +6 -5
- package/dist/components/GapSelect.d.cts +2 -1
- package/dist/components/GapSelect.d.ts +2 -1
- package/dist/components/GapSelect.js +5 -4
- package/dist/components/MultipleChoice.cjs +6 -5
- package/dist/components/MultipleChoice.d.cts +2 -1
- package/dist/components/MultipleChoice.d.ts +2 -1
- package/dist/components/MultipleChoice.js +5 -4
- package/dist/components/PronunciationFeedback.cjs +16 -0
- package/dist/components/PronunciationFeedback.cjs.map +1 -0
- package/dist/components/PronunciationFeedback.d.cts +67 -0
- package/dist/components/PronunciationFeedback.d.ts +67 -0
- package/dist/components/PronunciationFeedback.js +7 -0
- package/dist/components/PronunciationFeedback.js.map +1 -0
- package/dist/components/ReadAloud.cjs +21 -0
- package/dist/components/ReadAloud.cjs.map +1 -0
- package/dist/components/ReadAloud.d.cts +15 -0
- package/dist/components/ReadAloud.d.ts +15 -0
- package/dist/components/ReadAloud.js +12 -0
- package/dist/components/ReadAloud.js.map +1 -0
- package/dist/components/StimulusPanel.cjs +4 -4
- package/dist/components/StimulusPanel.d.cts +2 -1
- package/dist/components/StimulusPanel.d.ts +2 -1
- package/dist/components/StimulusPanel.js +3 -3
- package/dist/components/WrittenResponse.cjs +6 -5
- package/dist/components/WrittenResponse.d.cts +4 -3
- package/dist/components/WrittenResponse.d.ts +4 -3
- package/dist/components/WrittenResponse.js +5 -4
- package/dist/hooks/useSpeechRecorder.cjs +17 -0
- package/dist/hooks/useSpeechRecorder.cjs.map +1 -0
- package/dist/hooks/useSpeechRecorder.d.cts +127 -0
- package/dist/hooks/useSpeechRecorder.d.ts +127 -0
- package/dist/hooks/useSpeechRecorder.js +4 -0
- package/dist/hooks/useSpeechRecorder.js.map +1 -0
- package/dist/i18n/LkIntlProvider.cjs +7 -7
- package/dist/i18n/LkIntlProvider.d.cts +3 -2
- package/dist/i18n/LkIntlProvider.d.ts +3 -2
- package/dist/i18n/LkIntlProvider.js +1 -1
- package/dist/index.cjs +53 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +17 -12
- package/dist/index.js.map +1 -1
- package/dist/machine-CuwKqWXC.d.cts +26 -0
- package/dist/machine-CuwKqWXC.d.ts +26 -0
- package/dist/{strings-DPTyLpHt.d.cts → strings-l8Wv1Xax.d.ts} +230 -4
- package/dist/{strings-DPTyLpHt.d.ts → strings-wjAF2ONm.d.cts} +230 -4
- package/dist/theme/ThemeProvider.cjs +6 -6
- package/dist/theme/ThemeProvider.d.cts +4 -4
- package/dist/theme/ThemeProvider.d.ts +4 -4
- package/dist/theme/ThemeProvider.js +1 -1
- package/dist/theme/skin.css +612 -3
- package/package.json +33 -3
- package/dist/chunk-2GXSA322.cjs.map +0 -1
- package/dist/chunk-3Q4I4KT6.js.map +0 -1
- package/dist/chunk-5N7OLFHB.js.map +0 -1
- package/dist/chunk-AMGK7DDM.cjs.map +0 -1
- package/dist/chunk-DQERNAWI.js.map +0 -1
- package/dist/chunk-DQNVAXG6.js.map +0 -1
- package/dist/chunk-HT4FFZZQ.cjs.map +0 -1
- package/dist/chunk-J73TDY7J.cjs.map +0 -1
- package/dist/chunk-K3EA547J.cjs.map +0 -1
- package/dist/chunk-K7NMNOPI.cjs.map +0 -1
- package/dist/chunk-MA7GXUWC.cjs.map +0 -1
- package/dist/chunk-NVUFEMPZ.cjs.map +0 -1
- package/dist/chunk-PSHNTDKG.js.map +0 -1
- package/dist/chunk-PY53ABWC.js.map +0 -1
- package/dist/chunk-R7DI5UMU.js.map +0 -1
- package/dist/chunk-SBIJJ374.cjs.map +0 -1
- package/dist/chunk-UU2NV6SU.cjs.map +0 -1
- package/dist/chunk-W4MXRZAB.js.map +0 -1
- package/dist/chunk-XAGWBVK3.js.map +0 -1
- package/dist/chunk-YILH4ETT.js.map +0 -1
- package/dist/chunk-YZWXVZB3.js.map +0 -1
- package/dist/chunk-Z63JRG4M.cjs.map +0 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReadAloudData, SpeechAssessment, GradeRecord, ThemeTokens } from '@intellectif/lk-core';
|
|
3
|
+
import { a as LkStringsOverride } from '../strings-wjAF2ONm.cjs';
|
|
4
|
+
import '../machine-CuwKqWXC.cjs';
|
|
5
|
+
|
|
6
|
+
interface PronunciationFeedbackProps {
|
|
7
|
+
/**
|
|
8
|
+
* The item's reading and its language. Only these two fields, because they
|
|
9
|
+
* are the only ones a mark depends on — everything else about the activity
|
|
10
|
+
* belongs to whoever rendered it.
|
|
11
|
+
*/
|
|
12
|
+
data: Pick<ReadAloudData, 'referenceText' | 'locale'>;
|
|
13
|
+
/**
|
|
14
|
+
* The assessor's evidence. Checked with `validateSpeechAssessment` before it
|
|
15
|
+
* is aligned: see the note on this component about what a bad one costs.
|
|
16
|
+
*/
|
|
17
|
+
assessment: SpeechAssessment;
|
|
18
|
+
/**
|
|
19
|
+
* The grade the evidence produced, when one exists. Its `criteria` are what
|
|
20
|
+
* the dimensions are read from, because they are the numbers the learner was
|
|
21
|
+
* actually graded on. A grade that cannot be read — a score that is not a
|
|
22
|
+
* number between 0 and its maximum, a `passed` that is not a boolean — is
|
|
23
|
+
* shown as could-not-be-graded, never as a percentage made up from it.
|
|
24
|
+
*/
|
|
25
|
+
grade?: GradeRecord;
|
|
26
|
+
/**
|
|
27
|
+
* The learner's own take, playable. With it, each word that carries timings
|
|
28
|
+
* gets a button that plays just that word. A take the page refuses to play —
|
|
29
|
+
* a `blob:` URL under a Content-Security-Policy whose `media-src` does not
|
|
30
|
+
* allow one, most often — offers no such button, and the panel says the take
|
|
31
|
+
* cannot be played here.
|
|
32
|
+
*/
|
|
33
|
+
audioUrl?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Confidence above which a break note is shown, 0..1. **No default**: how
|
|
36
|
+
* confident an engine has to be before a pause is worth telling a learner
|
|
37
|
+
* about is a calibration, and the SDK has no calibrated answer. Without it no
|
|
38
|
+
* break note is shown at all.
|
|
39
|
+
*/
|
|
40
|
+
breakThreshold?: number;
|
|
41
|
+
/** The same, for the monotone note read off `assessment.prosody`. */
|
|
42
|
+
monotoneThreshold?: number;
|
|
43
|
+
/**
|
|
44
|
+
* BCP 47 tag stamped as `lang` on the root: the INTERFACE language, the one
|
|
45
|
+
* this component's own sentences are written in. It is not `data.locale`,
|
|
46
|
+
* which is the language of the reading and is put on the words themselves.
|
|
47
|
+
*/
|
|
48
|
+
locale?: string;
|
|
49
|
+
/** Per-instance token overrides, applied as inline CSS vars on the root. */
|
|
50
|
+
theme?: Partial<ThemeTokens>;
|
|
51
|
+
/** Overrides the SDK's chrome text for this panel. See {@link LkIntlProvider}. */
|
|
52
|
+
strings?: LkStringsOverride;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Public pronunciation-feedback panel: the core wrapped in
|
|
57
|
+
* `ActivityErrorBoundary` so a render failure (the dev throw for evidence
|
|
58
|
+
* `validateSpeechAssessment` refuses among them) degrades to an accessible
|
|
59
|
+
* fallback instead of crashing the host.
|
|
60
|
+
*
|
|
61
|
+
* **No `activityTitle`.** Its `data` is two fields of a read-aloud item and
|
|
62
|
+
* carries no title, so the production fallback is the unnamed one. Naming it
|
|
63
|
+
* would mean inventing a title for a panel that never had one.
|
|
64
|
+
*/
|
|
65
|
+
declare function PronunciationFeedback(props: PronunciationFeedbackProps): react_jsx_runtime.JSX.Element;
|
|
66
|
+
|
|
67
|
+
export { PronunciationFeedback, type PronunciationFeedbackProps };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReadAloudData, SpeechAssessment, GradeRecord, ThemeTokens } from '@intellectif/lk-core';
|
|
3
|
+
import { a as LkStringsOverride } from '../strings-l8Wv1Xax.js';
|
|
4
|
+
import '../machine-CuwKqWXC.js';
|
|
5
|
+
|
|
6
|
+
interface PronunciationFeedbackProps {
|
|
7
|
+
/**
|
|
8
|
+
* The item's reading and its language. Only these two fields, because they
|
|
9
|
+
* are the only ones a mark depends on — everything else about the activity
|
|
10
|
+
* belongs to whoever rendered it.
|
|
11
|
+
*/
|
|
12
|
+
data: Pick<ReadAloudData, 'referenceText' | 'locale'>;
|
|
13
|
+
/**
|
|
14
|
+
* The assessor's evidence. Checked with `validateSpeechAssessment` before it
|
|
15
|
+
* is aligned: see the note on this component about what a bad one costs.
|
|
16
|
+
*/
|
|
17
|
+
assessment: SpeechAssessment;
|
|
18
|
+
/**
|
|
19
|
+
* The grade the evidence produced, when one exists. Its `criteria` are what
|
|
20
|
+
* the dimensions are read from, because they are the numbers the learner was
|
|
21
|
+
* actually graded on. A grade that cannot be read — a score that is not a
|
|
22
|
+
* number between 0 and its maximum, a `passed` that is not a boolean — is
|
|
23
|
+
* shown as could-not-be-graded, never as a percentage made up from it.
|
|
24
|
+
*/
|
|
25
|
+
grade?: GradeRecord;
|
|
26
|
+
/**
|
|
27
|
+
* The learner's own take, playable. With it, each word that carries timings
|
|
28
|
+
* gets a button that plays just that word. A take the page refuses to play —
|
|
29
|
+
* a `blob:` URL under a Content-Security-Policy whose `media-src` does not
|
|
30
|
+
* allow one, most often — offers no such button, and the panel says the take
|
|
31
|
+
* cannot be played here.
|
|
32
|
+
*/
|
|
33
|
+
audioUrl?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Confidence above which a break note is shown, 0..1. **No default**: how
|
|
36
|
+
* confident an engine has to be before a pause is worth telling a learner
|
|
37
|
+
* about is a calibration, and the SDK has no calibrated answer. Without it no
|
|
38
|
+
* break note is shown at all.
|
|
39
|
+
*/
|
|
40
|
+
breakThreshold?: number;
|
|
41
|
+
/** The same, for the monotone note read off `assessment.prosody`. */
|
|
42
|
+
monotoneThreshold?: number;
|
|
43
|
+
/**
|
|
44
|
+
* BCP 47 tag stamped as `lang` on the root: the INTERFACE language, the one
|
|
45
|
+
* this component's own sentences are written in. It is not `data.locale`,
|
|
46
|
+
* which is the language of the reading and is put on the words themselves.
|
|
47
|
+
*/
|
|
48
|
+
locale?: string;
|
|
49
|
+
/** Per-instance token overrides, applied as inline CSS vars on the root. */
|
|
50
|
+
theme?: Partial<ThemeTokens>;
|
|
51
|
+
/** Overrides the SDK's chrome text for this panel. See {@link LkIntlProvider}. */
|
|
52
|
+
strings?: LkStringsOverride;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Public pronunciation-feedback panel: the core wrapped in
|
|
57
|
+
* `ActivityErrorBoundary` so a render failure (the dev throw for evidence
|
|
58
|
+
* `validateSpeechAssessment` refuses among them) degrades to an accessible
|
|
59
|
+
* fallback instead of crashing the host.
|
|
60
|
+
*
|
|
61
|
+
* **No `activityTitle`.** Its `data` is two fields of a read-aloud item and
|
|
62
|
+
* carries no title, so the production fallback is the unnamed one. Naming it
|
|
63
|
+
* would mean inventing a title for a panel that never had one.
|
|
64
|
+
*/
|
|
65
|
+
declare function PronunciationFeedback(props: PronunciationFeedbackProps): react_jsx_runtime.JSX.Element;
|
|
66
|
+
|
|
67
|
+
export { PronunciationFeedback, type PronunciationFeedbackProps };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
export { PronunciationFeedback } from '../chunk-TUVEJLOT.js';
|
|
3
|
+
import '../chunk-YORQQXGO.js';
|
|
4
|
+
import '../chunk-B4BCEQNO.js';
|
|
5
|
+
import '../chunk-AWQ53DON.js';
|
|
6
|
+
//# sourceMappingURL=PronunciationFeedback.js.map
|
|
7
|
+
//# sourceMappingURL=PronunciationFeedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"PronunciationFeedback.js"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkKIO6QXGT_cjs = require('../chunk-KIO6QXGT.cjs');
|
|
5
|
+
require('../chunk-YM64MS4G.cjs');
|
|
6
|
+
require('../chunk-UDCQTOVU.cjs');
|
|
7
|
+
require('../chunk-OD65OZIW.cjs');
|
|
8
|
+
require('../chunk-BRPEB43C.cjs');
|
|
9
|
+
require('../chunk-DPEY7DSE.cjs');
|
|
10
|
+
require('../chunk-UMDWVMB5.cjs');
|
|
11
|
+
require('../chunk-XOR4MPEN.cjs');
|
|
12
|
+
require('../chunk-VSFHJ7FB.cjs');
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
Object.defineProperty(exports, "ReadAloud", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunkKIO6QXGT_cjs.ReadAloud; }
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=ReadAloud.cjs.map
|
|
21
|
+
//# sourceMappingURL=ReadAloud.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"ReadAloud.cjs"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { c as ReadAloudProps } from '../strings-wjAF2ONm.cjs';
|
|
3
|
+
export { R as ReadAloudAssessResult, d as RecordingBinding } from '../strings-wjAF2ONm.cjs';
|
|
4
|
+
export { R as RecordedTake } from '../machine-CuwKqWXC.cjs';
|
|
5
|
+
import '@intellectif/lk-core';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Public Read Aloud activity: the core wrapped in `ActivityErrorBoundary` so a
|
|
9
|
+
* render failure (including the dev schema-validation throw and the
|
|
10
|
+
* missing-`upload` guard) degrades to an accessible fallback instead of
|
|
11
|
+
* crashing the host.
|
|
12
|
+
*/
|
|
13
|
+
declare function ReadAloud(props: ReadAloudProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { ReadAloud, ReadAloudProps };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { c as ReadAloudProps } from '../strings-l8Wv1Xax.js';
|
|
3
|
+
export { R as ReadAloudAssessResult, d as RecordingBinding } from '../strings-l8Wv1Xax.js';
|
|
4
|
+
export { R as RecordedTake } from '../machine-CuwKqWXC.js';
|
|
5
|
+
import '@intellectif/lk-core';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Public Read Aloud activity: the core wrapped in `ActivityErrorBoundary` so a
|
|
9
|
+
* render failure (including the dev schema-validation throw and the
|
|
10
|
+
* missing-`upload` guard) degrades to an accessible fallback instead of
|
|
11
|
+
* crashing the host.
|
|
12
|
+
*/
|
|
13
|
+
declare function ReadAloud(props: ReadAloudProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { ReadAloud, ReadAloudProps };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
export { ReadAloud } from '../chunk-5JFMXBH7.js';
|
|
3
|
+
import '../chunk-TUVEJLOT.js';
|
|
4
|
+
import '../chunk-MCO52PV5.js';
|
|
5
|
+
import '../chunk-YORQQXGO.js';
|
|
6
|
+
import '../chunk-RCMYEWBE.js';
|
|
7
|
+
import '../chunk-B4BCEQNO.js';
|
|
8
|
+
import '../chunk-DB4DLHN6.js';
|
|
9
|
+
import '../chunk-6N43WDVG.js';
|
|
10
|
+
import '../chunk-AWQ53DON.js';
|
|
11
|
+
//# sourceMappingURL=ReadAloud.js.map
|
|
12
|
+
//# sourceMappingURL=ReadAloud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"ReadAloud.js"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
4
|
+
var chunkCTW3G3EH_cjs = require('../chunk-CTW3G3EH.cjs');
|
|
5
|
+
require('../chunk-UMDWVMB5.cjs');
|
|
6
|
+
require('../chunk-VSFHJ7FB.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "StimulusPanel", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunkCTW3G3EH_cjs.StimulusPanel; }
|
|
13
13
|
});
|
|
14
14
|
//# sourceMappingURL=StimulusPanel.cjs.map
|
|
15
15
|
//# sourceMappingURL=StimulusPanel.cjs.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Stimulus, InteractionEvent } from '@intellectif/lk-core';
|
|
2
|
-
import { H as HtmlSanitizer,
|
|
2
|
+
import { H as HtmlSanitizer, e as RenderMode, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from '../strings-wjAF2ONm.cjs';
|
|
3
|
+
import '../machine-CuwKqWXC.cjs';
|
|
3
4
|
|
|
4
5
|
interface StimulusPanelProps {
|
|
5
6
|
stimulus: Stimulus;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Stimulus, InteractionEvent } from '@intellectif/lk-core';
|
|
2
|
-
import { H as HtmlSanitizer,
|
|
2
|
+
import { H as HtmlSanitizer, e as RenderMode, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from '../strings-l8Wv1Xax.js';
|
|
3
|
+
import '../machine-CuwKqWXC.js';
|
|
3
4
|
|
|
4
5
|
interface StimulusPanelProps {
|
|
5
6
|
stimulus: Stimulus;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { StimulusPanel } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
2
|
+
export { StimulusPanel } from '../chunk-AS2QGND5.js';
|
|
3
|
+
import '../chunk-DB4DLHN6.js';
|
|
4
|
+
import '../chunk-AWQ53DON.js';
|
|
5
5
|
//# sourceMappingURL=StimulusPanel.js.map
|
|
6
6
|
//# sourceMappingURL=StimulusPanel.js.map
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
4
|
+
var chunk4Y5TELVU_cjs = require('../chunk-4Y5TELVU.cjs');
|
|
5
|
+
require('../chunk-BRPEB43C.cjs');
|
|
6
|
+
require('../chunk-DPEY7DSE.cjs');
|
|
7
|
+
require('../chunk-UMDWVMB5.cjs');
|
|
7
8
|
require('../chunk-XOR4MPEN.cjs');
|
|
8
|
-
require('../chunk-
|
|
9
|
+
require('../chunk-VSFHJ7FB.cjs');
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
Object.defineProperty(exports, "WrittenResponse", {
|
|
13
14
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
15
|
+
get: function () { return chunk4Y5TELVU_cjs.WrittenResponse; }
|
|
15
16
|
});
|
|
16
17
|
//# sourceMappingURL=WrittenResponse.cjs.map
|
|
17
18
|
//# sourceMappingURL=WrittenResponse.cjs.map
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { W as WrittenResponseProps } from '../WrittenResponse-
|
|
3
|
-
export { a as WrittenResponseSubmission } from '../WrittenResponse-
|
|
4
|
-
export { H as HtmlSanitizer,
|
|
2
|
+
import { W as WrittenResponseProps } from '../WrittenResponse-rRpOr9W1.cjs';
|
|
3
|
+
export { a as WrittenResponseSubmission } from '../WrittenResponse-rRpOr9W1.cjs';
|
|
4
|
+
export { H as HtmlSanitizer, e as RenderMode, f as Renderable } from '../strings-wjAF2ONm.cjs';
|
|
5
5
|
import '@intellectif/lk-core';
|
|
6
|
+
import '../machine-CuwKqWXC.cjs';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Public Written Response activity: a labelled textarea with a live word
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { W as WrittenResponseProps } from '../WrittenResponse-
|
|
3
|
-
export { a as WrittenResponseSubmission } from '../WrittenResponse-
|
|
4
|
-
export { H as HtmlSanitizer,
|
|
2
|
+
import { W as WrittenResponseProps } from '../WrittenResponse-DrzI89Wg.js';
|
|
3
|
+
export { a as WrittenResponseSubmission } from '../WrittenResponse-DrzI89Wg.js';
|
|
4
|
+
export { H as HtmlSanitizer, e as RenderMode, f as Renderable } from '../strings-l8Wv1Xax.js';
|
|
5
5
|
import '@intellectif/lk-core';
|
|
6
|
+
import '../machine-CuwKqWXC.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Public Written Response activity: a labelled textarea with a live word
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { WrittenResponse } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
2
|
+
export { WrittenResponse } from '../chunk-U432HTUW.js';
|
|
3
|
+
import '../chunk-RCMYEWBE.js';
|
|
4
|
+
import '../chunk-B4BCEQNO.js';
|
|
5
|
+
import '../chunk-DB4DLHN6.js';
|
|
5
6
|
import '../chunk-6N43WDVG.js';
|
|
6
|
-
import '../chunk-
|
|
7
|
+
import '../chunk-AWQ53DON.js';
|
|
7
8
|
//# sourceMappingURL=WrittenResponse.js.map
|
|
8
9
|
//# sourceMappingURL=WrittenResponse.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkUDCQTOVU_cjs = require('../chunk-UDCQTOVU.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "CAPTURE_PROCESSOR_SOURCE", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkUDCQTOVU_cjs.CAPTURE_PROCESSOR_SOURCE; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "useSpeechRecorder", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkUDCQTOVU_cjs.useSpeechRecorder; }
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=useSpeechRecorder.cjs.map
|
|
17
|
+
//# sourceMappingURL=useSpeechRecorder.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"useSpeechRecorder.cjs"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { a as SpeechRecorderStatus, S as SpeechRecorderError, R as RecordedTake } from '../machine-CuwKqWXC.cjs';
|
|
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 };
|
|
@@ -0,0 +1,127 @@
|
|
|
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 };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"useSpeechRecorder.js"}
|