@ai-matrx/media 0.14.0 → 0.15.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 +23 -0
- package/dist/react.cjs +84 -4
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +35 -2
- package/dist/react.d.ts +35 -2
- package/dist/react.js +93 -4
- package/dist/react.js.map +1 -1
- package/dist/speech.cjs +1689 -0
- package/dist/speech.cjs.map +1 -0
- package/dist/speech.d.cts +565 -0
- package/dist/speech.d.ts +565 -0
- package/dist/speech.js +1683 -0
- package/dist/speech.js.map +1 -0
- package/dist/tts-config-JbF86KIt.d.cts +149 -0
- package/dist/tts-config-JbF86KIt.d.ts +149 -0
- package/dist/voices.d.cts +3 -149
- package/dist/voices.d.ts +3 -149
- package/package.json +15 -4
package/dist/react.d.cts
CHANGED
|
@@ -3,6 +3,7 @@ import react__default, { SVGProps, HTMLAttributes, InputHTMLAttributes, ReactNod
|
|
|
3
3
|
import { MediaRefLike, DurableSrc, MediaUploadOptions, MediaActionKind } from './index.cjs';
|
|
4
4
|
import { M as MediaUploadEntry } from './use-media-upload-v5Uq9Ruq.cjs';
|
|
5
5
|
import { Volume2TapButton } from '@ai-matrx/tap-target/buttons';
|
|
6
|
+
import { SpeakRequest, PlaybackItemStatus, PlaybackSnapshot, pausePlayback, resumePlayback, skipPlayback, removePlaybackItem, playPlaybackItem } from '@ai-matrx/media/speech';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* src/react/cn.ts — conditional class join with last-wins Tailwind conflict
|
|
@@ -345,6 +346,7 @@ declare function MediaLightbox({ open, onClose, mediaRef, fileName, alt, as, aut
|
|
|
345
346
|
|
|
346
347
|
type ReadAloudStatus = "idle" | "loading" | "playing" | "paused" | "error";
|
|
347
348
|
type TapVariant = ComponentProps<typeof Volume2TapButton>["variant"];
|
|
349
|
+
type ReadAloudButtonSize = "default" | "compact";
|
|
348
350
|
interface ReadAloudButtonProps {
|
|
349
351
|
status: ReadAloudStatus;
|
|
350
352
|
onPress: () => void;
|
|
@@ -353,11 +355,42 @@ interface ReadAloudButtonProps {
|
|
|
353
355
|
/** Nothing to read (empty text) or the host forbids it right now. */
|
|
354
356
|
disabled?: boolean;
|
|
355
357
|
variant?: TapVariant;
|
|
358
|
+
/**
|
|
359
|
+
* "compact" is the message-footer size: the 32px cell (28px pill) every chat footer control uses,
|
|
360
|
+
* instead of the 38px default box. It sets the geometry only; it wins over `variant`.
|
|
361
|
+
*/
|
|
362
|
+
size?: ReadAloudButtonSize;
|
|
356
363
|
className?: string;
|
|
357
364
|
/** Label for the idle state. Default "Read aloud". */
|
|
358
365
|
label?: string;
|
|
359
366
|
}
|
|
360
|
-
declare function ReadAloudButton({ status, onPress, error, disabled, variant, className, label, }: ReadAloudButtonProps): react.JSX.Element;
|
|
367
|
+
declare function ReadAloudButton({ status, onPress, error, disabled, variant: requestedVariant, size, className, label, }: ReadAloudButtonProps): react.JSX.Element;
|
|
368
|
+
|
|
369
|
+
declare function usePlaybackSnapshot(): PlaybackSnapshot;
|
|
370
|
+
type UseSpeechOptions = Omit<SpeakRequest, "text" | "sample"> & {
|
|
371
|
+
/** Re-adopt the queue's active item when it is speaking exactly this text. */
|
|
372
|
+
adoptText?: string;
|
|
373
|
+
};
|
|
374
|
+
declare function useSpeech({ adoptText, ...request }?: UseSpeechOptions): {
|
|
375
|
+
speak: (text: string) => string;
|
|
376
|
+
status: PlaybackItemStatus | null;
|
|
377
|
+
error: string | null;
|
|
378
|
+
itemId: string | null;
|
|
379
|
+
isMine: boolean;
|
|
380
|
+
pause: typeof pausePlayback;
|
|
381
|
+
resume: typeof resumePlayback;
|
|
382
|
+
skip: typeof skipPlayback;
|
|
383
|
+
remove: typeof removePlaybackItem;
|
|
384
|
+
playItem: typeof playPlaybackItem;
|
|
385
|
+
};
|
|
386
|
+
/** The queue's item status in the read-aloud button's vocabulary. */
|
|
387
|
+
declare function readAloudStatusOf(status: PlaybackItemStatus | null): ReadAloudStatus;
|
|
388
|
+
declare function useReadAloud(text: string, options?: UseSpeechOptions): {
|
|
389
|
+
status: ReadAloudStatus;
|
|
390
|
+
error: string | null;
|
|
391
|
+
onPress: () => void;
|
|
392
|
+
speak: (text: string) => string;
|
|
393
|
+
};
|
|
361
394
|
|
|
362
395
|
interface ReadAloudLanguagePickerProps {
|
|
363
396
|
value: string;
|
|
@@ -366,4 +399,4 @@ interface ReadAloudLanguagePickerProps {
|
|
|
366
399
|
}
|
|
367
400
|
declare function ReadAloudLanguagePicker({ value, onChange, className }: ReadAloudLanguagePickerProps): react.JSX.Element;
|
|
368
401
|
|
|
369
|
-
export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PauseIcon, PenToolIcon, PlayIcon, PlusIcon, ReadAloudButton, type ReadAloudButtonProps, ReadAloudLanguagePicker, type ReadAloudLanguagePickerProps, type ReadAloudStatus, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, useMediaDropzone };
|
|
402
|
+
export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PauseIcon, PenToolIcon, PlayIcon, PlusIcon, ReadAloudButton, type ReadAloudButtonProps, type ReadAloudButtonSize, ReadAloudLanguagePicker, type ReadAloudLanguagePickerProps, type ReadAloudStatus, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, type UseSpeechOptions, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, readAloudStatusOf, useMediaDropzone, usePlaybackSnapshot, useReadAloud, useSpeech };
|
package/dist/react.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import react__default, { SVGProps, HTMLAttributes, InputHTMLAttributes, ReactNod
|
|
|
3
3
|
import { MediaRefLike, DurableSrc, MediaUploadOptions, MediaActionKind } from './index.js';
|
|
4
4
|
import { M as MediaUploadEntry } from './use-media-upload-Dg2HSvTq.js';
|
|
5
5
|
import { Volume2TapButton } from '@ai-matrx/tap-target/buttons';
|
|
6
|
+
import { SpeakRequest, PlaybackItemStatus, PlaybackSnapshot, pausePlayback, resumePlayback, skipPlayback, removePlaybackItem, playPlaybackItem } from '@ai-matrx/media/speech';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* src/react/cn.ts — conditional class join with last-wins Tailwind conflict
|
|
@@ -345,6 +346,7 @@ declare function MediaLightbox({ open, onClose, mediaRef, fileName, alt, as, aut
|
|
|
345
346
|
|
|
346
347
|
type ReadAloudStatus = "idle" | "loading" | "playing" | "paused" | "error";
|
|
347
348
|
type TapVariant = ComponentProps<typeof Volume2TapButton>["variant"];
|
|
349
|
+
type ReadAloudButtonSize = "default" | "compact";
|
|
348
350
|
interface ReadAloudButtonProps {
|
|
349
351
|
status: ReadAloudStatus;
|
|
350
352
|
onPress: () => void;
|
|
@@ -353,11 +355,42 @@ interface ReadAloudButtonProps {
|
|
|
353
355
|
/** Nothing to read (empty text) or the host forbids it right now. */
|
|
354
356
|
disabled?: boolean;
|
|
355
357
|
variant?: TapVariant;
|
|
358
|
+
/**
|
|
359
|
+
* "compact" is the message-footer size: the 32px cell (28px pill) every chat footer control uses,
|
|
360
|
+
* instead of the 38px default box. It sets the geometry only; it wins over `variant`.
|
|
361
|
+
*/
|
|
362
|
+
size?: ReadAloudButtonSize;
|
|
356
363
|
className?: string;
|
|
357
364
|
/** Label for the idle state. Default "Read aloud". */
|
|
358
365
|
label?: string;
|
|
359
366
|
}
|
|
360
|
-
declare function ReadAloudButton({ status, onPress, error, disabled, variant, className, label, }: ReadAloudButtonProps): react.JSX.Element;
|
|
367
|
+
declare function ReadAloudButton({ status, onPress, error, disabled, variant: requestedVariant, size, className, label, }: ReadAloudButtonProps): react.JSX.Element;
|
|
368
|
+
|
|
369
|
+
declare function usePlaybackSnapshot(): PlaybackSnapshot;
|
|
370
|
+
type UseSpeechOptions = Omit<SpeakRequest, "text" | "sample"> & {
|
|
371
|
+
/** Re-adopt the queue's active item when it is speaking exactly this text. */
|
|
372
|
+
adoptText?: string;
|
|
373
|
+
};
|
|
374
|
+
declare function useSpeech({ adoptText, ...request }?: UseSpeechOptions): {
|
|
375
|
+
speak: (text: string) => string;
|
|
376
|
+
status: PlaybackItemStatus | null;
|
|
377
|
+
error: string | null;
|
|
378
|
+
itemId: string | null;
|
|
379
|
+
isMine: boolean;
|
|
380
|
+
pause: typeof pausePlayback;
|
|
381
|
+
resume: typeof resumePlayback;
|
|
382
|
+
skip: typeof skipPlayback;
|
|
383
|
+
remove: typeof removePlaybackItem;
|
|
384
|
+
playItem: typeof playPlaybackItem;
|
|
385
|
+
};
|
|
386
|
+
/** The queue's item status in the read-aloud button's vocabulary. */
|
|
387
|
+
declare function readAloudStatusOf(status: PlaybackItemStatus | null): ReadAloudStatus;
|
|
388
|
+
declare function useReadAloud(text: string, options?: UseSpeechOptions): {
|
|
389
|
+
status: ReadAloudStatus;
|
|
390
|
+
error: string | null;
|
|
391
|
+
onPress: () => void;
|
|
392
|
+
speak: (text: string) => string;
|
|
393
|
+
};
|
|
361
394
|
|
|
362
395
|
interface ReadAloudLanguagePickerProps {
|
|
363
396
|
value: string;
|
|
@@ -366,4 +399,4 @@ interface ReadAloudLanguagePickerProps {
|
|
|
366
399
|
}
|
|
367
400
|
declare function ReadAloudLanguagePicker({ value, onChange, className }: ReadAloudLanguagePickerProps): react.JSX.Element;
|
|
368
401
|
|
|
369
|
-
export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PauseIcon, PenToolIcon, PlayIcon, PlusIcon, ReadAloudButton, type ReadAloudButtonProps, ReadAloudLanguagePicker, type ReadAloudLanguagePickerProps, type ReadAloudStatus, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, useMediaDropzone };
|
|
402
|
+
export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PauseIcon, PenToolIcon, PlayIcon, PlusIcon, ReadAloudButton, type ReadAloudButtonProps, type ReadAloudButtonSize, ReadAloudLanguagePicker, type ReadAloudLanguagePickerProps, type ReadAloudStatus, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, type UseSpeechOptions, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, readAloudStatusOf, useMediaDropzone, usePlaybackSnapshot, useReadAloud, useSpeech };
|
package/dist/react.js
CHANGED
|
@@ -2484,10 +2484,12 @@ function ReadAloudButton({
|
|
|
2484
2484
|
onPress,
|
|
2485
2485
|
error,
|
|
2486
2486
|
disabled = false,
|
|
2487
|
-
variant,
|
|
2487
|
+
variant: requestedVariant,
|
|
2488
|
+
size = "default",
|
|
2488
2489
|
className,
|
|
2489
2490
|
label = "Read aloud"
|
|
2490
2491
|
}) {
|
|
2492
|
+
const variant = size === "compact" ? "group" : requestedVariant;
|
|
2491
2493
|
if (status === "playing") {
|
|
2492
2494
|
return /* @__PURE__ */ jsx9(PauseTapButton, { variant, onClick: onPress, disabled, ariaLabel: "Pause", className });
|
|
2493
2495
|
}
|
|
@@ -2516,10 +2518,93 @@ function ReadAloudButton({
|
|
|
2516
2518
|
);
|
|
2517
2519
|
}
|
|
2518
2520
|
|
|
2521
|
+
// src/react/use-speech.ts
|
|
2522
|
+
import { useCallback as useCallback8, useState as useState10, useSyncExternalStore } from "react";
|
|
2523
|
+
import {
|
|
2524
|
+
getPlaybackSnapshot,
|
|
2525
|
+
pausePlayback,
|
|
2526
|
+
playPlaybackItem,
|
|
2527
|
+
removePlaybackItem,
|
|
2528
|
+
resumePlayback,
|
|
2529
|
+
skipPlayback,
|
|
2530
|
+
subscribePlayback,
|
|
2531
|
+
speak as speakText
|
|
2532
|
+
} from "@ai-matrx/media/speech";
|
|
2533
|
+
var cached = getPlaybackSnapshot();
|
|
2534
|
+
function subscribe(onChange) {
|
|
2535
|
+
return subscribePlayback((snapshot) => {
|
|
2536
|
+
cached = snapshot;
|
|
2537
|
+
onChange();
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
var read = () => cached;
|
|
2541
|
+
function usePlaybackSnapshot() {
|
|
2542
|
+
return useSyncExternalStore(subscribe, read, read);
|
|
2543
|
+
}
|
|
2544
|
+
function useSpeech({ adoptText, ...request } = {}) {
|
|
2545
|
+
const { items, currentId } = usePlaybackSnapshot();
|
|
2546
|
+
const [itemId, setItemId] = useState10(null);
|
|
2547
|
+
const adoptedId = !itemId && adoptText && currentId ? items.find(
|
|
2548
|
+
(i) => i.id === currentId && i.text === adoptText && (i.status === "playing" || i.status === "paused" || i.status === "loading")
|
|
2549
|
+
)?.id ?? null : null;
|
|
2550
|
+
const effectiveId = itemId ?? adoptedId;
|
|
2551
|
+
const { engine, voice, purpose, processMarkdown = true, label, dictionarySurfaceKey, language, speed } = request;
|
|
2552
|
+
const speak = useCallback8(
|
|
2553
|
+
(text) => {
|
|
2554
|
+
const { id } = speakText({
|
|
2555
|
+
text,
|
|
2556
|
+
engine,
|
|
2557
|
+
voice,
|
|
2558
|
+
purpose,
|
|
2559
|
+
processMarkdown,
|
|
2560
|
+
label,
|
|
2561
|
+
dictionarySurfaceKey,
|
|
2562
|
+
language,
|
|
2563
|
+
speed
|
|
2564
|
+
});
|
|
2565
|
+
setItemId(id);
|
|
2566
|
+
return id;
|
|
2567
|
+
},
|
|
2568
|
+
[engine, voice, purpose, processMarkdown, label, dictionarySurfaceKey, language, speed]
|
|
2569
|
+
);
|
|
2570
|
+
const item = effectiveId ? items.find((i) => i.id === effectiveId) : void 0;
|
|
2571
|
+
const status = item?.status ?? null;
|
|
2572
|
+
return {
|
|
2573
|
+
speak,
|
|
2574
|
+
status,
|
|
2575
|
+
error: item?.error ?? null,
|
|
2576
|
+
itemId,
|
|
2577
|
+
isMine: effectiveId !== null && effectiveId === currentId,
|
|
2578
|
+
pause: pausePlayback,
|
|
2579
|
+
resume: resumePlayback,
|
|
2580
|
+
skip: skipPlayback,
|
|
2581
|
+
remove: removePlaybackItem,
|
|
2582
|
+
playItem: playPlaybackItem
|
|
2583
|
+
};
|
|
2584
|
+
}
|
|
2585
|
+
function readAloudStatusOf(status) {
|
|
2586
|
+
if (status === "playing") return "playing";
|
|
2587
|
+
if (status === "paused") return "paused";
|
|
2588
|
+
if (status === "loading" || status === "queued") return "loading";
|
|
2589
|
+
if (status === "error") return "error";
|
|
2590
|
+
return "idle";
|
|
2591
|
+
}
|
|
2592
|
+
function useReadAloud(text, options = {}) {
|
|
2593
|
+
const { speak, status, error, pause, resume } = useSpeech({ adoptText: text, ...options });
|
|
2594
|
+
const state = readAloudStatusOf(status);
|
|
2595
|
+
const onPress = useCallback8(() => {
|
|
2596
|
+
if (state === "loading") return;
|
|
2597
|
+
if (state === "playing") void pause();
|
|
2598
|
+
else if (state === "paused") void resume();
|
|
2599
|
+
else if (text.trim()) speak(text);
|
|
2600
|
+
}, [state, text, speak, pause, resume]);
|
|
2601
|
+
return { status: state, error, onPress, speak };
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2519
2604
|
// src/react/read-aloud-language-picker.tsx
|
|
2520
2605
|
import { Button, Popover, PopoverContent, PopoverTrigger } from "@ai-matrx/design-system";
|
|
2521
2606
|
import { Check, Languages } from "lucide-react";
|
|
2522
|
-
import { useState as
|
|
2607
|
+
import { useState as useState11 } from "react";
|
|
2523
2608
|
|
|
2524
2609
|
// src/voices/read-aloud-languages.ts
|
|
2525
2610
|
var READ_ALOUD_LANGUAGES = [
|
|
@@ -2547,7 +2632,7 @@ function readAloudLanguage(code) {
|
|
|
2547
2632
|
// src/react/read-aloud-language-picker.tsx
|
|
2548
2633
|
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2549
2634
|
function ReadAloudLanguagePicker({ value, onChange, className }) {
|
|
2550
|
-
const [open, setOpen] =
|
|
2635
|
+
const [open, setOpen] = useState11(false);
|
|
2551
2636
|
const selected = readAloudLanguage(value);
|
|
2552
2637
|
return /* @__PURE__ */ jsxs7(Popover, { open, onOpenChange: setOpen, children: [
|
|
2553
2638
|
/* @__PURE__ */ jsx10(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(
|
|
@@ -2643,6 +2728,10 @@ export {
|
|
|
2643
2728
|
VolumeXIcon,
|
|
2644
2729
|
XIcon,
|
|
2645
2730
|
cn,
|
|
2646
|
-
|
|
2731
|
+
readAloudStatusOf,
|
|
2732
|
+
useMediaDropzone,
|
|
2733
|
+
usePlaybackSnapshot,
|
|
2734
|
+
useReadAloud,
|
|
2735
|
+
useSpeech
|
|
2647
2736
|
};
|
|
2648
2737
|
//# sourceMappingURL=react.js.map
|