dsh-live-voice-debugger 0.7.0 → 0.7.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.
- package/ARCHITECTURE.md +1 -1
- package/lib/client.js +9 -2
- package/package.json +1 -1
package/ARCHITECTURE.md
CHANGED
|
@@ -12,7 +12,7 @@ Attempt details show measured HTTP WAV request bytes, input/output samples/rates
|
|
|
12
12
|
|
|
13
13
|
Segment rows provide localized icon-only play, exact-range WAV download, and optional speech retranscription. Retranscription uses the currently selected `qwen-http`, `whisper-http`, browser-local `whisper-browser` / `qwen-browser`, or native Browser SpeechRecognition engine with boundary context (minimum 800 ms). Browser-local models must be downloaded in Settings first; retry never downloads models or falls back to HTTP. Native retry is available only when safe external-audio-track support is verified, processes existing saved segments under the selected local/remote-processing and language-pack requirements, and never falls back to microphone capture. Native Browser live capture still does not record original speech. Retranscription requires finished capture and adds audit attempts without editing the composer or executing commands; older v1 services simply omit it. Selecting speech or silence in the timeline loads that exact segment in the shared player without autoplay; zoom never changes the selected audio range.
|
|
14
14
|
|
|
15
|
-
The recording timeline has a single sample-clock track with two accessible slider handles and a draggable selected band for a non-destructive zoom window. Pointer capture supports mouse/touch/pen; keyboard arrows, Page Up/Down and Home/End resize or pan with clamped bounds. The icon-only reset has a localized title and accessible name; rendered segments and pins are clipped/remapped without changing stored ranges or playback. The end follows live growth until narrowed. Switching sessions resets the window.
|
|
15
|
+
The recording timeline has a single sample-clock track with two accessible slider handles and a draggable selected band for a non-destructive zoom window. Pointer capture supports mouse/touch/pen; keyboard arrows, Page Up/Down and Home/End resize or pan with clamped bounds. The icon-only reset has a localized title and accessible name; rendered segments and pins are clipped/remapped without changing stored ranges or playback. The end follows live growth until narrowed. Switching sessions resets the window. The segment list uses the same overlapping sample ranges as the visible timeline, including partially visible segments; transcript search applies within that window and ranks normalized exact text/phrases, whole and partial words, then bounded typo matches; only successful nonempty transcripts appear while a query is active, and clearing restores chronological segments. A prominent storage card always summarizes the full unfiltered list, session count and encoded-audio size. Unknown/invalid legacy counts produce an explicit measured lower bound, not zero or a discarded total. Loading/failure is not a known empty archive. Confirmed bulk removal snapshots eligible IDs across all sources (including stars), rechecks each before the existing service remove call, preserves active/pending sessions and reports removed/skipped/failed counts without claiming transaction-wide atomicity. New sessions never join a confirmed batch; service replacement, unmount or page hide stop future calls, not an already-dispatched removal. Cancel receives initial focus, Escape cancels before execution, and the result receives focus after completion. Detail playback/retries are released while clearing; invalid source filters reset after removal. No DSH conversation, exported file or future-capture setting is deleted.
|
|
16
16
|
|
|
17
17
|
Totals, per-session sizes and deletion previews share one decimal-SI formatter (1 KB = 1,000 bytes), automatically selecting B/KB/MB/GB/TB and capping units at TB. It shows at most one fractional digit, no thousands grouping, and uses the explicit DSH UI locale (Portuguese decimal comma), not browser or speech language. Values rounding to 1000 promote to the next unit where available. Encoded audio size is not origin quota, JS memory or WAV export size; older services without byte counts show unavailable rather than zero.
|
|
18
18
|
|
package/lib/client.js
CHANGED
|
@@ -3102,7 +3102,6 @@ function RecordingDetail({
|
|
|
3102
3102
|
};
|
|
3103
3103
|
const [search, setSearch] = import_react25.default.useState("");
|
|
3104
3104
|
import_react25.default.useEffect(() => setSearch(""), [session.id, service]);
|
|
3105
|
-
const matchedSegments = import_react25.default.useMemo(() => searchSegments(segments, search), [segments, search]);
|
|
3106
3105
|
const length = Math.max(1, session.savedSamples);
|
|
3107
3106
|
const [windowStart, setWindowStart] = import_react25.default.useState(0);
|
|
3108
3107
|
const [windowEnd, setWindowEnd] = import_react25.default.useState(null);
|
|
@@ -3113,6 +3112,14 @@ function RecordingDetail({
|
|
|
3113
3112
|
const viewEnd = Math.max(1, Math.min(length, windowEnd ?? length));
|
|
3114
3113
|
const viewStart = Math.max(0, Math.min(windowStart, viewEnd - 1));
|
|
3115
3114
|
const viewLength = viewEnd - viewStart;
|
|
3115
|
+
const visibleSegments = import_react25.default.useMemo(
|
|
3116
|
+
() => segments.filter((segment) => segment.endSample > viewStart && segment.startSample < viewEnd),
|
|
3117
|
+
[segments, viewStart, viewEnd]
|
|
3118
|
+
);
|
|
3119
|
+
const matchedSegments = import_react25.default.useMemo(
|
|
3120
|
+
() => searchSegments(visibleSegments, search),
|
|
3121
|
+
[visibleSegments, search]
|
|
3122
|
+
);
|
|
3116
3123
|
const inWindow = (sample) => sample >= viewStart && sample <= viewEnd;
|
|
3117
3124
|
const position = (sample) => (sample - viewStart) / viewLength * 100 + "%";
|
|
3118
3125
|
const segmentName = (segment) => (commandsFor(segment).length ? copy.recordings.eventCommand : segment.kind === "speech" ? copy.recordings.speech : copy.recordings.silence) + " \xB7 " + duration(segment.startSample, session.sampleRate) + " \u2014 " + duration(segment.endSample, session.sampleRate);
|
|
@@ -3226,7 +3233,7 @@ function RecordingDetail({
|
|
|
3226
3233
|
setWindowEnd(null);
|
|
3227
3234
|
}
|
|
3228
3235
|
}
|
|
3229
|
-
), /* @__PURE__ */ import_react25.default.createElement("div", { className: "dlvd-timeline", role: "group", "aria-label": copy.recordings.timeline },
|
|
3236
|
+
), /* @__PURE__ */ import_react25.default.createElement("div", { className: "dlvd-timeline", role: "group", "aria-label": copy.recordings.timeline }, visibleSegments.map((segment) => /* @__PURE__ */ import_react25.default.createElement(
|
|
3230
3237
|
"button",
|
|
3231
3238
|
{
|
|
3232
3239
|
key: segment.id,
|