@seams/voice-capture 0.68.1 → 0.69.1

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.
@@ -8,7 +8,30 @@ import { VoicePrompt, leaveSurface } from "./prompt.js";
8
8
  //#region src/card/surface.ts
9
9
  const LABEL = "Say this with your voice";
10
10
  const PROMPT_LABEL = "Say this sentence";
11
- const PROMPT_MESSAGE = "Read it naturally, then pause.";
11
+ /**
12
+ * The status line before a recording: empty, so the sentence is the one text to read. It holds
13
+ * "Opening microphone…", a loading line or a problem with the recording.
14
+ */
15
+ const PROMPT_MESSAGE = "";
16
+ /** The colours that a phrase card reads. */
17
+ const PHRASE_CARD_COLORS = [
18
+ "colorBackground",
19
+ "textPrimary",
20
+ "textSecondary",
21
+ "textMuted",
22
+ "borderPrimary",
23
+ "surface",
24
+ "surface3",
25
+ "buttonBackground",
26
+ "textButton",
27
+ "error",
28
+ "info",
29
+ "voiceLine",
30
+ "voiceEcho",
31
+ "voiceEchoDeep",
32
+ "voiceFill",
33
+ "voicePixelBackground"
34
+ ];
12
35
  /**
13
36
  * Shows the given sentence in the prompt. The surface records clips with the quality check, and
14
37
  * stays open so the caller can show its check and the result in the same card. A too quiet or
@@ -27,6 +50,14 @@ var CardSurface = class {
27
50
  pressed;
28
51
  /** Back, when the card shows it apart from Close. */
29
52
  back;
53
+ /** Minimize, when the host can hide the card. */
54
+ minimize;
55
+ minimizedHook;
56
+ progressedHook;
57
+ /** The person pressed Minimize, and the card has not asked to show again since. */
58
+ minimized = false;
59
+ /** The last stage that the host heard, as a key. */
60
+ progress = "";
30
61
  recorder = null;
31
62
  recording = null;
32
63
  choice = null;
@@ -55,8 +86,10 @@ var CardSurface = class {
55
86
  this.element.setAttribute("role", "dialog");
56
87
  this.element.setAttribute("aria-modal", "true");
57
88
  this.element.setAttribute("aria-label", LABEL);
89
+ paintColors(this.element, input.colors);
58
90
  this.prompt = new VoicePrompt(document, LABEL, sentence);
59
- this.prompt.title.textContent = PROMPT_LABEL;
91
+ const promptLabel = input.context?.sentenceLabel ?? PROMPT_LABEL;
92
+ this.prompt.title.textContent = promptLabel;
60
93
  const shown = /[.!?]$/.test(sentence) ? sentence : `${sentence}.`;
61
94
  this.prompt.phrase.textContent = shown;
62
95
  delete this.prompt.phrase.dataset.voiceidPhrase;
@@ -65,7 +98,11 @@ var CardSurface = class {
65
98
  const controls = frame.controls ?? "close";
66
99
  this.pressed = frame.pressed;
67
100
  const back = controls === "close" ? null : this.prompt.showBack(controls === "back_and_close");
101
+ if (input.context) this.prompt.showContext(input.context.label, input.context.text);
68
102
  this.back = back === this.prompt.cancel ? null : back;
103
+ this.minimizedHook = frame.minimized;
104
+ this.progressedHook = frame.progressed;
105
+ this.minimize = frame.minimized ? this.prompt.showMinimize() : null;
69
106
  const handedOverPrompt = handedOver?.querySelector(":scope > .seams-voiceid-prompt") ?? null;
70
107
  const rows = handedOverPrompt ? handedOverRows(handedOverPrompt) : null;
71
108
  if (handedOverPrompt) {
@@ -74,7 +111,7 @@ var CardSurface = class {
74
111
  this.autoStart = false;
75
112
  }
76
113
  this.card = new PhraseCard(this.prompt, {
77
- label: PROMPT_LABEL,
114
+ label: promptLabel,
78
115
  sentence: shown,
79
116
  message: PROMPT_MESSAGE,
80
117
  action: "Record"
@@ -89,10 +126,13 @@ var CardSurface = class {
89
126
  const corner = controls === "back" ? this.pressBack : this.pressClose;
90
127
  this.prompt.cancel.addEventListener("click", corner);
91
128
  this.back?.addEventListener("click", this.pressBack);
129
+ this.minimize?.addEventListener("click", this.pressMinimize);
92
130
  this.element.addEventListener("cancel", this.cancel);
93
131
  outer.addEventListener("abort", this.cancel);
94
132
  if (handedOver) handedOver.replaceWith(this.element);
95
133
  else parent.appendChild(this.element);
134
+ const voiceLine = input.voiceLine ?? themeVoiceLine(this.prompt.element);
135
+ if (voiceLine === "pixels") this.prompt.useVoiceLine(voiceLine);
96
136
  if (frame.hugged) this.element.classList.add("seams-voiceid-hugged");
97
137
  this.unmounted = frame.mounted?.(this.element);
98
138
  if (rows || this.autoStart) this.prompt.element.focus({ preventScroll: true });
@@ -107,6 +147,11 @@ var CardSurface = class {
107
147
  this.recording = recording;
108
148
  if (this.view) {
109
149
  this.view = null;
150
+ this.report({
151
+ stage: "recording",
152
+ done: 0,
153
+ total: 0
154
+ });
110
155
  this.card.showPrompt();
111
156
  } else if (this.autoStart) this.begin(recording);
112
157
  this.autoStart = false;
@@ -117,6 +162,21 @@ var CardSurface = class {
117
162
  if (this.closed) return Promise.resolve("closed");
118
163
  this.settleChoice("replaced");
119
164
  this.view = view;
165
+ if (view.kind === "check") {
166
+ const done = view.segments.filter((state) => state === "done" || state === "skip").length;
167
+ this.report({
168
+ stage: "checking",
169
+ done,
170
+ total: view.segments.length
171
+ });
172
+ } else {
173
+ this.report({
174
+ stage: "result",
175
+ done: 0,
176
+ total: 0
177
+ });
178
+ this.needPerson();
179
+ }
120
180
  this.card.show(view);
121
181
  return new Promise((resolve) => {
122
182
  this.choice = resolve;
@@ -135,6 +195,7 @@ var CardSurface = class {
135
195
  this.prompt.cancel.removeEventListener("click", this.pressBack);
136
196
  this.prompt.cancel.removeEventListener("click", this.pressClose);
137
197
  this.back?.removeEventListener("click", this.pressBack);
198
+ this.minimize?.removeEventListener("click", this.pressMinimize);
138
199
  this.card.dispose();
139
200
  this.prompt.dispose();
140
201
  leaveSurface(this.element);
@@ -150,6 +211,11 @@ var CardSurface = class {
150
211
  };
151
212
  begin(recording) {
152
213
  this.started = true;
214
+ this.report({
215
+ stage: "recording",
216
+ done: 0,
217
+ total: 0
218
+ });
153
219
  this.prompt.record.disabled = true;
154
220
  this.prompt.status.textContent = this.speechDetectorReady ? "Opening microphone…" : `Loading ${captureConfig().label}…`;
155
221
  this.attempt(recording, this.autoStart);
@@ -198,8 +264,14 @@ var CardSurface = class {
198
264
  };
199
265
  /** The end of speech starts the check in place; every other capture event is the prompt's. */
200
266
  capture = (event) => {
201
- if (event.kind === "processing") this.card.beginCheck();
202
- else this.prompt.capture(event);
267
+ if (event.kind === "processing") {
268
+ this.report({
269
+ stage: "checking",
270
+ done: 0,
271
+ total: 0
272
+ });
273
+ this.card.beginCheck();
274
+ } else this.prompt.capture(event);
203
275
  };
204
276
  retry(message, action = "Try again") {
205
277
  this.started = false;
@@ -207,6 +279,31 @@ var CardSurface = class {
207
279
  this.prompt.record.textContent = action;
208
280
  this.prompt.ready(message);
209
281
  this.prompt.record.focus();
282
+ this.report({
283
+ stage: "recording",
284
+ done: 0,
285
+ total: 0
286
+ });
287
+ this.needPerson();
288
+ }
289
+ /** Tells the host each new stage of the card. */
290
+ report(progress) {
291
+ const key = `${progress.stage}:${progress.done}:${progress.total}`;
292
+ if (key === this.progress || this.closed) return;
293
+ this.progress = key;
294
+ this.progressedHook?.(progress);
295
+ }
296
+ /** The person asks the host to hide the card. A host that showed it again can hide it again. */
297
+ pressMinimize = () => {
298
+ if (this.closed) return;
299
+ this.minimized = true;
300
+ this.minimizedHook?.(true);
301
+ };
302
+ /** The card needs the person: the host shows the card that it hid. */
303
+ needPerson() {
304
+ if (!this.minimized) return;
305
+ this.minimized = false;
306
+ this.minimizedHook?.(false);
210
307
  }
211
308
  settleChoice(choice) {
212
309
  const settle = this.choice;
@@ -233,6 +330,18 @@ var CardSurface = class {
233
330
  if (this.outer.aborted) this.close();
234
331
  };
235
332
  };
333
+ /** Sets the card's own colours. Keys that a card does not read are left out. */
334
+ function paintColors(element, colors) {
335
+ if (!colors) return;
336
+ for (const key of PHRASE_CARD_COLORS) {
337
+ const value = colors[key];
338
+ if (value) element.style.setProperty(`--seams-colors-${key}`, value);
339
+ }
340
+ }
341
+ /** The theme's `--seams-shape-voiceLine`: `pixels`, or else the wave lines. */
342
+ function themeVoiceLine(element) {
343
+ return getComputedStyle(element).getPropertyValue("--seams-shape-voiceLine").trim() === "pixels" ? "pixels" : "wave";
344
+ }
236
345
  /** A failed early load runs again when Record needs the detector, and shows its error there. */
237
346
  function ignoreEarlyLoad() {}
238
347
  /** The rows that the handed-over card shows now. */
@@ -1,2 +1,2 @@
1
- import { n as beamPalette, t as VoiceVisual } from "../chunks/visual-CeEQ8QkM.js";
1
+ import { n as beamPalette, t as VoiceVisual } from "../chunks/visual-rOVJCP2w.js";
2
2
  export { VoiceVisual, beamPalette };
@@ -1450,7 +1450,7 @@ const GREY_BAND = {
1450
1450
  below: "#536471"
1451
1451
  }
1452
1452
  };
1453
- /** The theme's `voiceBeam`, the name of a Beam palette, or the default one. */
1453
+ /** The theme's `voiceBeam`, the name of a Beam palette, or the default one. (`none`: no Beam.) */
1454
1454
  function beamPalette(value) {
1455
1455
  const name = value.trim();
1456
1456
  return Object.hasOwn(Va, name) ? name : DEFAULT_BEAM;
@@ -1472,6 +1472,7 @@ var VoiceVisual = class {
1472
1472
  this.glow.className = "seams-voiceid-glow";
1473
1473
  this.glow.setAttribute("aria-hidden", "true");
1474
1474
  this.render();
1475
+ queueMicrotask(this.render);
1475
1476
  const nonce = styleNonce();
1476
1477
  if (nonce) for (const style of this.glow.querySelectorAll("style")) style.nonce = nonce;
1477
1478
  this.themeObserver = new MutationObserver(this.render);
@@ -1484,6 +1485,10 @@ var VoiceVisual = class {
1484
1485
  attributeFilter: ["data-theme"]
1485
1486
  });
1486
1487
  }
1488
+ /** Draws the voice as wave lines (the default) or as columns of pixels. */
1489
+ setLineStyle(style) {
1490
+ this.ribbon.setLineStyle(style);
1491
+ }
1487
1492
  listen() {
1488
1493
  this.setPhase("listening");
1489
1494
  }
@@ -1528,8 +1533,14 @@ var VoiceVisual = class {
1528
1533
  }
1529
1534
  render = () => {
1530
1535
  if (this.disposed) return;
1536
+ const beam = getComputedStyle(this.prompt).getPropertyValue("--seams-colors-voiceBeam").trim();
1537
+ this.glow.hidden = beam === "none";
1538
+ if (this.glow.hidden) {
1539
+ render(null, this.glow);
1540
+ return;
1541
+ }
1531
1542
  const mode = (this.prompt.closest("[data-theme]")?.getAttribute("data-theme") ?? this.prompt.ownerDocument.documentElement.getAttribute("data-theme")) === "light" ? "light" : "dark";
1532
- const palette = beamPalette(getComputedStyle(this.prompt).getPropertyValue("--seams-colors-voiceBeam"));
1543
+ const palette = beamPalette(beam);
1533
1544
  render(createElement(VoiceBeamView, {
1534
1545
  className: "seams-voiceid-beam",
1535
1546
  theme: mode,
@@ -1,6 +1,6 @@
1
- export { openPhraseCard, type PhraseCardControl, type PhraseCardControls, type PhraseCardFrame, type PhraseCardInput, } from './surface';
1
+ export { openPhraseCard, type PhraseCardColor, type PhraseCardColors, type PhraseCardContext, type PhraseCardControl, type PhraseCardControls, type PhraseCardFrame, type PhraseCardInput, type PhraseCardProgress, } from './surface';
2
2
  export type { PhraseCheckView, PhraseChoice, PhraseRecording, PhraseResultView, PhraseSegmentState, PhraseSurface, PhraseText, PhraseView, } from './types';
3
3
  export { leaveSurface, VoicePrompt, type PhraseDisplay, type PromptChange } from './prompt';
4
4
  export { PhraseCard, type HandedOverRows, type PromptCopy } from './phraseCard';
5
- export { VoiceRibbon, type VoiceCheckingStyle } from './ribbon';
5
+ export { VoiceRibbon, type VoiceCheckingStyle, type VoiceLineStyle } from './ribbon';
6
6
  export { VoiceVisual } from './visual';
@@ -1,5 +1,5 @@
1
1
  import type { VoiceCaptureEvent } from '../microphone';
2
- import type { VoiceCheckingStyle } from './ribbon';
2
+ import type { VoiceCheckingStyle, VoiceLineStyle } from './ribbon';
3
3
  /** How the card shows a phrase: by default as it is, with a capital letter and a full stop. */
4
4
  export type PhraseDisplay = (phrase: string) => string;
5
5
  /** A new state of the card's rows. Rows that it leaves out keep their content. */
@@ -45,12 +45,24 @@ export declare class VoicePrompt {
45
45
  constructor(document: Document, label: string, phrase: string, checking?: VoiceCheckingStyle,
46
46
  /** The text to show for a phrase, such as the phrase with its commas. */
47
47
  display?: PhraseDisplay);
48
+ /** Draws the voice as wave lines (the default) or as columns of pixels. */
49
+ useVoiceLine(style: VoiceLineStyle): void;
50
+ /**
51
+ * Shows the text that the sentence speaks for, such as the note that a spoken summary signs,
52
+ * above the sentence. It stays for the check and the result.
53
+ */
54
+ showContext(label: string, text: string): void;
48
55
  /**
49
56
  * In an app's dialog with a step before this card, Back in the leading corner returns to that
50
57
  * step. With `close`, Close stays in the trailing corner and ends the whole dialog; without it,
51
58
  * Back takes Close's place. Each one ends the card as cancelled. The result is the Back control.
52
59
  */
53
60
  showBack(close: boolean): HTMLButtonElement;
61
+ /**
62
+ * Minimize in the trailing corner, beside Close. It stays in the check, where Close is hidden,
63
+ * so the person can hide the card while the check goes on. The result is the control.
64
+ */
65
+ showMinimize(): HTMLButtonElement;
54
66
  /**
55
67
  * Moves the rows to a new state. The rows whose content changes fade out together, take their
56
68
  * new content and fade in one after another; the other rows stay still. A change that comes
@@ -2,6 +2,8 @@ import type { VoiceActivityEvent } from '../microphone';
2
2
  type RibbonPhase = 'idle' | 'listening' | 'processing';
3
3
  /** How the line shows that the voice is being checked. */
4
4
  export type VoiceCheckingStyle = 'ring' | 'segments';
5
+ /** How the card draws the voice while it listens: sine wave lines, or columns of pixels. */
6
+ export type VoiceLineStyle = 'wave' | 'pixels';
5
7
  /** Visual feedback from recorder activity. Never opens or retains an audio stream. */
6
8
  export declare class VoiceRibbon {
7
9
  private readonly checking;
@@ -25,8 +27,19 @@ export declare class VoiceRibbon {
25
27
  private target;
26
28
  private level;
27
29
  private stopped;
30
+ private lineStyle;
31
+ /** The pixel style's dots by column, top row first. Made when the style is first chosen. */
32
+ private pixels;
33
+ /** The level of each column, the newest at the right end. */
34
+ private readonly pixelLevels;
35
+ /** The rows that each column shows now, above and below the middle row. */
36
+ private readonly pixelHeights;
37
+ private pixelClock;
28
38
  constructor(document: Document, checking?: VoiceCheckingStyle);
29
39
  readonly readLevel: () => number;
40
+ /** Draws the voice as wave lines (the default) or as columns of pixels. */
41
+ setLineStyle(style: VoiceLineStyle): void;
42
+ private makePixels;
30
43
  /** The voice line's width now: 1, or the theme's `voiceLineWidth`. */
31
44
  private lineWidth;
32
45
  setPhase(phase: RibbonPhase): void;
@@ -43,8 +56,12 @@ export declare class VoiceRibbon {
43
56
  private wake;
44
57
  private readonly draw;
45
58
  private idleAmplitude;
59
+ /** Adds the level of each step at the right end; the older columns move left. */
60
+ private stepPixels;
46
61
  private paint;
47
62
  private paintLine;
63
+ /** Each column shows the middle dot and as many rows above and below it as its level. */
64
+ private paintPixels;
48
65
  private paintSegments;
49
66
  /** Each segment brightens one beat after the one before it, from the resting line's opacity. */
50
67
  private segmentOpacity;
@@ -1,5 +1,5 @@
1
1
  export declare const ROW_OUT_MS = 150;
2
- export declare const ROW_IN_MS = 200;
3
- export declare const ROW_IN_DELAY_MS = 20;
4
- export declare const ROW_STAGGER_MS = 30;
2
+ export declare const ROW_IN_MS = 140;
3
+ export declare const ROW_IN_DELAY_MS = 0;
4
+ export declare const ROW_STAGGER_MS = 20;
5
5
  export declare const ROW_EASE = "cubic-bezier(0.2, 0, 0, 1)";
@@ -1,4 +1,5 @@
1
1
  import { type VoiceRecordingOptions } from '../microphone';
2
+ import type { VoiceLineStyle } from './ribbon';
2
3
  import type { PhraseSurface } from './types';
3
4
  /** What the host page adds around the card. Every field is optional. */
4
5
  export type PhraseCardFrame = Readonly<{
@@ -14,6 +15,16 @@ export type PhraseCardFrame = Readonly<{
14
15
  controls?: PhraseCardControls;
15
16
  /** Runs when the person presses Back or Close, before the card ends. Escape is not a press. */
16
17
  pressed?(control: PhraseCardControl): void;
18
+ /**
19
+ * With it, the card draws Minimize in the trailing corner, beside Close, also in the check.
20
+ * A press runs `minimized(true)`. The card does not hide itself: the host hides it, and the
21
+ * recording, the check and the caller's work go on. The card runs `minimized(false)` when it
22
+ * needs the person again: on a result, and when a recording needs another try. The host can
23
+ * show the card again before that.
24
+ */
25
+ minimized?(minimized: boolean): void;
26
+ /** Runs on each new stage of the card, so the host can show the progress of a hidden card. */
27
+ progressed?(progress: PhraseCardProgress): void;
17
28
  /** The host sizes its frame to the surface, so the card follows the frame. */
18
29
  hugged?: boolean;
19
30
  /** Runs when the surface is in the document. Its return value runs when the surface closes. */
@@ -23,6 +34,16 @@ export type PhraseCardFrame = Readonly<{
23
34
  export type PhraseCardControls = 'close' | 'back' | 'back_and_close';
24
35
  /** One corner control of a phrase card. */
25
36
  export type PhraseCardControl = 'back' | 'close';
37
+ /**
38
+ * The stage of a phrase card: it records the sentence (or waits for Record), it checks the
39
+ * recording, or it shows a result.
40
+ */
41
+ export type PhraseCardProgress = Readonly<{
42
+ stage: 'recording' | 'checking' | 'result';
43
+ /** The parts of the check that are over, of `total`. Both are 0 outside a check. */
44
+ done: number;
45
+ total: number;
46
+ }>;
26
47
  export type PhraseCardInput = Readonly<{
27
48
  sentence: string;
28
49
  signal: AbortSignal;
@@ -35,6 +56,49 @@ export type PhraseCardInput = Readonly<{
35
56
  * start audio without a press, the card stays with its Record button.
36
57
  */
37
58
  autoStart?: boolean;
59
+ /**
60
+ * The text that the sentence speaks for, such as the note that a spoken summary signs. With
61
+ * it, the card is a form: the text in a soft box under its label, the sentence centred in a
62
+ * box under its own label, and one button at the foot that is the voice line while the card
63
+ * records. The text stays for the check and the result.
64
+ */
65
+ context?: PhraseCardContext;
66
+ /**
67
+ * How the card draws the voice while it listens: `wave`, sine wave lines (the default), or
68
+ * `pixels`, columns of dots in blue tones. Without it, the theme value `--seams-shape-voiceLine`
69
+ * (`wave` or `pixels`) decides, so a Wallet host can choose it with its theme.
70
+ */
71
+ voiceLine?: VoiceLineStyle;
72
+ /**
73
+ * The card's colours, as CSS colours, for example `{ buttonBackground: '#1d9bf0' }`. Each one
74
+ * sets the CSS variable `--seams-colors-<key>` on this card, over the page's own value. A
75
+ * Seams Wallet app sets the same keys in `appearance.theme.colors`.
76
+ */
77
+ colors?: PhraseCardColors;
78
+ }>;
79
+ /** The colours that a phrase card reads. */
80
+ declare const PHRASE_CARD_COLORS: readonly [
81
+ /** The card, its text, its lines and its soft boxes. */
82
+ 'colorBackground', 'textPrimary', 'textSecondary', 'textMuted', 'borderPrimary', 'surface',
83
+ /** The segments of a check that have not run yet. */
84
+ 'surface3',
85
+ /** The main button (Record, the voice line of a form card, Done) and its text. */
86
+ 'buttonBackground', 'textButton',
87
+ /** A failed check, and a held one. */
88
+ 'error', 'info',
89
+ /** The voice line, its echoes, and the bands of the pixel style. */
90
+ 'voiceLine', 'voiceEcho', 'voiceEchoDeep',
91
+ /** A form card: the fill of the sentence's box, and the button behind the pixels. */
92
+ 'voiceFill', 'voicePixelBackground'];
93
+ export type PhraseCardColor = (typeof PHRASE_CARD_COLORS)[number];
94
+ export type PhraseCardColors = Partial<Readonly<Record<PhraseCardColor, string>>>;
95
+ /** The text that a phrase card shows above its sentence. */
96
+ export type PhraseCardContext = Readonly<{
97
+ /** The label above the text, such as "Your note on @alice". */
98
+ label: string;
99
+ text: string;
100
+ /** The label above the sentence, such as "Read this aloud to post". Default: "Say this sentence". */
101
+ sentenceLabel?: string;
38
102
  }>;
39
103
  /**
40
104
  * Shows the given sentence in the prompt. The surface records clips with the quality check, and
@@ -42,3 +106,4 @@ export type PhraseCardInput = Readonly<{
42
106
  * interrupted recording stays on the surface for another try.
43
107
  */
44
108
  export declare function openPhraseCard(input: PhraseCardInput): PhraseSurface;
109
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { type VoiceBeamColorVariant } from 'voice-glow';
2
2
  import type { VoiceActivityEvent } from '../microphone';
3
- import { type VoiceCheckingStyle } from './ribbon';
4
- /** The theme's `voiceBeam`, the name of a Beam palette, or the default one. */
3
+ import { type VoiceCheckingStyle, type VoiceLineStyle } from './ribbon';
4
+ /** The theme's `voiceBeam`, the name of a Beam palette, or the default one. (`none`: no Beam.) */
5
5
  export declare function beamPalette(value: string): VoiceBeamColorVariant;
6
6
  /** Shared by enrollment, unlock and signing. The recorder remains the only audio owner. */
7
7
  export declare class VoiceVisual {
@@ -13,6 +13,8 @@ export declare class VoiceVisual {
13
13
  private phase;
14
14
  private disposed;
15
15
  constructor(document: Document, prompt: HTMLElement, checking: VoiceCheckingStyle);
16
+ /** Draws the voice as wave lines (the default) or as columns of pixels. */
17
+ setLineStyle(style: VoiceLineStyle): void;
16
18
  listen(): void;
17
19
  add(event: VoiceActivityEvent): void;
18
20
  checking(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seams/voice-capture",
3
- "version": "0.68.1",
3
+ "version": "0.69.1",
4
4
  "type": "module",
5
5
  "description": "Records one spoken sentence in the browser, with speech detection, a quality check and a phrase card",
6
6
  "license": "Apache-2.0",