dsh-realtime-audio-ws 0.1.0 → 0.1.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.
- package/lib/client/index.js +31 -23
- package/package.json +2 -2
- package/src/client/index.ts +12 -3
- package/lib/client/index.d.ts +0 -192
- package/lib/client/index.d.ts.map +0 -1
- package/lib/client/index.js.map +0 -1
package/lib/client/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* The browser face: microphone in, speaker out, over the host route.
|
|
3
4
|
*
|
|
@@ -22,25 +23,33 @@
|
|
|
22
23
|
* worse. That is a deliberate, disclosed trade: swap it for a worklet once the app page's `script-src` has
|
|
23
24
|
* actually been read, rather than shipping a capture path that a policy might silently kill.
|
|
24
25
|
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.INJECTED_KEY = exports.GLOBAL_KEY = exports.MAX_BACKLOG_SECONDS = exports.CAPTURE_BUFFER = exports.SAMPLE_RATE = exports.DEFAULT_PATH = exports.inject = exports.name = void 0;
|
|
28
|
+
exports.socketUrl = socketUrl;
|
|
29
|
+
exports.pcm16FromFloat32 = pcm16FromFloat32;
|
|
30
|
+
exports.float32FromPcm16 = float32FromPcm16;
|
|
31
|
+
exports.defaultDeps = defaultDeps;
|
|
32
|
+
exports.createAudioClient = createAudioClient;
|
|
33
|
+
exports.apply = apply;
|
|
25
34
|
/** Browser-side plugin name. */
|
|
26
|
-
|
|
35
|
+
exports.name = 'realtime-audio-client';
|
|
27
36
|
/**
|
|
28
37
|
* No client services. The socket, the device and the audio graph are all this plugin's own, so it injects
|
|
29
38
|
* nothing — and a client face that needs nothing cannot be broken by another plugin's absence.
|
|
30
39
|
*/
|
|
31
|
-
|
|
40
|
+
exports.inject = [];
|
|
32
41
|
/** Where the host route lives. Duplicated from the host package because a client face cannot import it. */
|
|
33
|
-
|
|
42
|
+
exports.DEFAULT_PATH = '/dsh-realtime/audio';
|
|
34
43
|
/** The session's declared rate. The graph is opened at this rate or the client refuses to run. */
|
|
35
|
-
|
|
44
|
+
exports.SAMPLE_RATE = 24_000;
|
|
36
45
|
/** Capture chunk in samples. 1024 at 24 kHz is ~43 ms: the 2^10 floor the API allows, so latency is lowest. */
|
|
37
|
-
|
|
46
|
+
exports.CAPTURE_BUFFER = 1024;
|
|
38
47
|
/** Backlog past which incoming speech is dropped rather than queued — the same rule the host carries. */
|
|
39
|
-
|
|
48
|
+
exports.MAX_BACKLOG_SECONDS = 0.5;
|
|
40
49
|
/** Global the client publishes itself on. There is no UI surface yet; this is how it is started. */
|
|
41
|
-
|
|
50
|
+
exports.GLOBAL_KEY = '__dshRealtimeAudio';
|
|
42
51
|
/** Optional host-injected settings. A future index-injection row may set the path; the default matches. */
|
|
43
|
-
|
|
52
|
+
exports.INJECTED_KEY = '__DSH_REALTIME_AUDIO__';
|
|
44
53
|
// ---- pure helpers --------------------------------------------------------------------------------------
|
|
45
54
|
/**
|
|
46
55
|
* The socket URL for the host route.
|
|
@@ -49,7 +58,7 @@ export const INJECTED_KEY = '__DSH_REALTIME_AUDIO__';
|
|
|
49
58
|
* @param path - the route pathname.
|
|
50
59
|
* @returns the URL, or undefined when this page cannot host a socket at all.
|
|
51
60
|
*/
|
|
52
|
-
|
|
61
|
+
function socketUrl(location, path) {
|
|
53
62
|
if (location === undefined || location.host === '')
|
|
54
63
|
return undefined;
|
|
55
64
|
// An https page may not open a ws:// socket — the browser blocks it as mixed content — so the scheme has
|
|
@@ -67,7 +76,7 @@ export function socketUrl(location, path) {
|
|
|
67
76
|
* @param input - samples in the range [-1, 1].
|
|
68
77
|
* @returns the same samples as little-endian PCM16 bytes.
|
|
69
78
|
*/
|
|
70
|
-
|
|
79
|
+
function pcm16FromFloat32(input) {
|
|
71
80
|
const out = new Int16Array(input.length);
|
|
72
81
|
// `entries()` rather than an index: under `noUncheckedIndexedAccess` an indexed read is
|
|
73
82
|
// `number | undefined`, and guarding that would add a branch that can never be taken at runtime.
|
|
@@ -83,7 +92,7 @@ export function pcm16FromFloat32(input) {
|
|
|
83
92
|
* @param bytes - the frame.
|
|
84
93
|
* @returns samples in [-1, 1).
|
|
85
94
|
*/
|
|
86
|
-
|
|
95
|
+
function float32FromPcm16(bytes) {
|
|
87
96
|
const samples = new Int16Array(bytes.buffer, bytes.byteOffset, Math.floor(bytes.byteLength / 2));
|
|
88
97
|
const out = new Float32Array(samples.length);
|
|
89
98
|
for (const [index, sample] of samples.entries())
|
|
@@ -98,7 +107,7 @@ export function float32FromPcm16(bytes) {
|
|
|
98
107
|
* @returns the production dependencies. Every one may be absent, which is why `start` reports rather than
|
|
99
108
|
* throws: a page without a microphone API is a fact about the page, not a defect in the caller.
|
|
100
109
|
*/
|
|
101
|
-
|
|
110
|
+
function defaultDeps(scope = globalThis) {
|
|
102
111
|
const media = scope.navigator?.mediaDevices;
|
|
103
112
|
const Audio = scope.AudioContext;
|
|
104
113
|
const Socket = scope.WebSocket;
|
|
@@ -116,7 +125,7 @@ export function defaultDeps(scope = globalThis) {
|
|
|
116
125
|
* @param deps - the outside world, injected so every path is testable.
|
|
117
126
|
* @returns the start/stop/state handle.
|
|
118
127
|
*/
|
|
119
|
-
|
|
128
|
+
function createAudioClient(deps) {
|
|
120
129
|
let current = { kind: 'idle' };
|
|
121
130
|
let socket;
|
|
122
131
|
let context;
|
|
@@ -152,13 +161,13 @@ export function createAudioClient(deps) {
|
|
|
152
161
|
const samples = float32FromPcm16(bytes);
|
|
153
162
|
if (samples.length === 0)
|
|
154
163
|
return;
|
|
155
|
-
const buffer = context.createBuffer(1, samples.length, SAMPLE_RATE);
|
|
164
|
+
const buffer = context.createBuffer(1, samples.length, exports.SAMPLE_RATE);
|
|
156
165
|
buffer.getChannelData(0).set(samples);
|
|
157
166
|
const now = context.currentTime;
|
|
158
167
|
const at = Math.max(now, playsAt);
|
|
159
168
|
// Unbuffered, like the host: audio that is already late is dropped rather than played behind, because a
|
|
160
169
|
// queue that grows converts a stutter into a permanent delay that never recovers.
|
|
161
|
-
if (at - now > MAX_BACKLOG_SECONDS)
|
|
170
|
+
if (at - now > exports.MAX_BACKLOG_SECONDS)
|
|
162
171
|
return;
|
|
163
172
|
const source = context.createBufferSource();
|
|
164
173
|
source.buffer = buffer;
|
|
@@ -172,7 +181,7 @@ export function createAudioClient(deps) {
|
|
|
172
181
|
return fail('the audio graph went away before the socket opened');
|
|
173
182
|
}
|
|
174
183
|
const source = context.createMediaStreamSource(stream);
|
|
175
|
-
const node = context.createScriptProcessor(CAPTURE_BUFFER, 1, 1);
|
|
184
|
+
const node = context.createScriptProcessor(exports.CAPTURE_BUFFER, 1, 1);
|
|
176
185
|
node.onaudioprocess = (event) => {
|
|
177
186
|
const pcm16 = pcm16FromFloat32(event.inputBuffer.getChannelData(0));
|
|
178
187
|
socket?.send(new Uint8Array(pcm16.buffer));
|
|
@@ -197,7 +206,7 @@ export function createAudioClient(deps) {
|
|
|
197
206
|
const start = async () => {
|
|
198
207
|
if (current.kind === 'live')
|
|
199
208
|
return current;
|
|
200
|
-
const url = socketUrl(deps.location, deps.injected?.path ?? DEFAULT_PATH);
|
|
209
|
+
const url = socketUrl(deps.location, deps.injected?.path ?? exports.DEFAULT_PATH);
|
|
201
210
|
if (url === undefined)
|
|
202
211
|
return fail('this page has no location to open a socket against');
|
|
203
212
|
if (deps.getUserMedia === undefined)
|
|
@@ -216,13 +225,13 @@ export function createAudioClient(deps) {
|
|
|
216
225
|
// user whether to grant it or to look somewhere else.
|
|
217
226
|
return fail(error instanceof Error ? error.message : String(error));
|
|
218
227
|
}
|
|
219
|
-
context = deps.createAudioContext(SAMPLE_RATE);
|
|
220
|
-
if (context.sampleRate !== SAMPLE_RATE) {
|
|
228
|
+
context = deps.createAudioContext(exports.SAMPLE_RATE);
|
|
229
|
+
if (context.sampleRate !== exports.SAMPLE_RATE) {
|
|
221
230
|
// Refuse rather than mislabel. Streaming 48 kHz samples declared as 24 kHz arrives at half speed and
|
|
222
231
|
// sounds like a provider fault, which is the most expensive possible way to learn about a resampler.
|
|
223
232
|
const opened = context.sampleRate;
|
|
224
233
|
release();
|
|
225
|
-
return fail(`the audio graph opened at ${String(opened)} Hz, not ${String(SAMPLE_RATE)}`);
|
|
234
|
+
return fail(`the audio graph opened at ${String(opened)} Hz, not ${String(exports.SAMPLE_RATE)}`);
|
|
226
235
|
}
|
|
227
236
|
const opened = deps.createSocket(url);
|
|
228
237
|
socket = opened;
|
|
@@ -250,9 +259,9 @@ export function createAudioClient(deps) {
|
|
|
250
259
|
*
|
|
251
260
|
* @param ctx - the client context, used only to own the lifetime.
|
|
252
261
|
*/
|
|
253
|
-
|
|
262
|
+
function apply(ctx) {
|
|
254
263
|
const client = createAudioClient(defaultDeps());
|
|
255
|
-
globalThis[GLOBAL_KEY] = {
|
|
264
|
+
globalThis[exports.GLOBAL_KEY] = {
|
|
256
265
|
start: () => client.start(),
|
|
257
266
|
stop: () => { client.stop(); },
|
|
258
267
|
state: () => client.state(),
|
|
@@ -260,4 +269,3 @@ export function apply(ctx) {
|
|
|
260
269
|
// A held microphone and a live audio graph must not outlive the plugin that opened them.
|
|
261
270
|
ctx.effect(() => () => { client.stop(); }, 'realtime-audio-client');
|
|
262
271
|
}
|
|
263
|
-
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-realtime-audio-ws",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "The host end of the client half's transport: a WebSocket upgrade route that bridges microphone audio in and agent speech out.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"@types/ws": "^8.18.2"
|
|
65
65
|
},
|
|
66
66
|
"scripts": {
|
|
67
|
-
"build": "tsc -b",
|
|
67
|
+
"build": "tsc -b && tsc -p tsconfig.client.json",
|
|
68
68
|
"typecheck": "tsc -b --dry"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/src/client/index.ts
CHANGED
|
@@ -23,8 +23,6 @@
|
|
|
23
23
|
* actually been read, rather than shipping a capture path that a policy might silently kill.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
|
27
|
-
|
|
28
26
|
/** Browser-side plugin name. */
|
|
29
27
|
export const name = 'realtime-audio-client'
|
|
30
28
|
|
|
@@ -83,6 +81,17 @@ export interface SocketLike {
|
|
|
83
81
|
onclose: (() => void) | null
|
|
84
82
|
}
|
|
85
83
|
|
|
84
|
+
/**
|
|
85
|
+
* The slice of a client Cordis context this plugin uses.
|
|
86
|
+
*
|
|
87
|
+
* Structural, and not only for testability: this face is served as a single CommonJS module, so any import
|
|
88
|
+
* it carried would have to be resolvable by whatever the module table hands the bundle. It needs one
|
|
89
|
+
* method, so it states one and imports nothing at all.
|
|
90
|
+
*/
|
|
91
|
+
export interface ClientContextLike {
|
|
92
|
+
effect(run: unknown, label?: string): unknown
|
|
93
|
+
}
|
|
94
|
+
|
|
86
95
|
/** Everything this plugin touches outside itself, injectable so every path is testable. */
|
|
87
96
|
export interface ClientAudioDeps {
|
|
88
97
|
readonly location: LocationLike | undefined
|
|
@@ -328,7 +337,7 @@ export function createAudioClient(deps: ClientAudioDeps): ClientAudio {
|
|
|
328
337
|
*
|
|
329
338
|
* @param ctx - the client context, used only to own the lifetime.
|
|
330
339
|
*/
|
|
331
|
-
export function apply(ctx:
|
|
340
|
+
export function apply(ctx: ClientContextLike): void {
|
|
332
341
|
const client = createAudioClient(defaultDeps())
|
|
333
342
|
;(globalThis as unknown as Record<string, unknown>)[GLOBAL_KEY] = {
|
|
334
343
|
start: () => client.start(),
|
package/lib/client/index.d.ts
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The browser face: microphone in, speaker out, over the host route.
|
|
3
|
-
*
|
|
4
|
-
* This is the client half of the transport. `dsh-realtime-audio-ws` claims the socket on the host and
|
|
5
|
-
* bridges it to the agent's audio events; this file opens that socket, captures the microphone into it, and
|
|
6
|
-
* plays what comes back.
|
|
7
|
-
*
|
|
8
|
-
* **One file, on purpose.** A client face is served as a single resource (`<package>/client.js`), so a
|
|
9
|
-
* relative value import would emit a second file the loader never serves. Everything therefore lives here,
|
|
10
|
-
* including the API shapes it needs.
|
|
11
|
-
*
|
|
12
|
-
* **No DOM lib, also on purpose.** The browser APIs are described structurally and read off `globalThis`
|
|
13
|
-
* through one cast, so this compiles in the package's ordinary program — no second tsconfig, no DOM lib,
|
|
14
|
-
* no bundler — and every path is testable by injecting fakes. `standard-browser-types` would have bought
|
|
15
|
-
* accurate types for six objects at the cost of a whole second build face; this is the cheaper trade.
|
|
16
|
-
*
|
|
17
|
-
* **`ScriptProcessorNode`, and why.** The modern capture path is an `AudioWorklet`, whose module must be
|
|
18
|
-
* fetched from a URL — a `blob:` URL, which a page's Content-Security-Policy can refuse. The desktop app
|
|
19
|
-
* demonstrably *has* a CSP (a `connect-src 'none'` string is in its bundle, governing the shell pages), and
|
|
20
|
-
* I have not read the app page's policy. `ScriptProcessorNode` needs no URL, no module fetch and no policy
|
|
21
|
-
* grant, and it runs in the page, so the whole capture path is testable. It is deprecated and its latency is
|
|
22
|
-
* worse. That is a deliberate, disclosed trade: swap it for a worklet once the app page's `script-src` has
|
|
23
|
-
* actually been read, rather than shipping a capture path that a policy might silently kill.
|
|
24
|
-
*/
|
|
25
|
-
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
26
|
-
/** Browser-side plugin name. */
|
|
27
|
-
export declare const name = "realtime-audio-client";
|
|
28
|
-
/**
|
|
29
|
-
* No client services. The socket, the device and the audio graph are all this plugin's own, so it injects
|
|
30
|
-
* nothing — and a client face that needs nothing cannot be broken by another plugin's absence.
|
|
31
|
-
*/
|
|
32
|
-
export declare const inject: string[];
|
|
33
|
-
/** Where the host route lives. Duplicated from the host package because a client face cannot import it. */
|
|
34
|
-
export declare const DEFAULT_PATH = "/dsh-realtime/audio";
|
|
35
|
-
/** The session's declared rate. The graph is opened at this rate or the client refuses to run. */
|
|
36
|
-
export declare const SAMPLE_RATE = 24000;
|
|
37
|
-
/** Capture chunk in samples. 1024 at 24 kHz is ~43 ms: the 2^10 floor the API allows, so latency is lowest. */
|
|
38
|
-
export declare const CAPTURE_BUFFER = 1024;
|
|
39
|
-
/** Backlog past which incoming speech is dropped rather than queued — the same rule the host carries. */
|
|
40
|
-
export declare const MAX_BACKLOG_SECONDS = 0.5;
|
|
41
|
-
/** Global the client publishes itself on. There is no UI surface yet; this is how it is started. */
|
|
42
|
-
export declare const GLOBAL_KEY = "__dshRealtimeAudio";
|
|
43
|
-
/** Optional host-injected settings. A future index-injection row may set the path; the default matches. */
|
|
44
|
-
export declare const INJECTED_KEY = "__DSH_REALTIME_AUDIO__";
|
|
45
|
-
export interface LocationLike {
|
|
46
|
-
readonly protocol: string;
|
|
47
|
-
readonly host: string;
|
|
48
|
-
}
|
|
49
|
-
export interface TrackLike {
|
|
50
|
-
stop(): void;
|
|
51
|
-
readonly kind?: string;
|
|
52
|
-
}
|
|
53
|
-
export interface StreamLike {
|
|
54
|
-
getTracks(): TrackLike[];
|
|
55
|
-
}
|
|
56
|
-
export interface MediaNodeLike {
|
|
57
|
-
connect(target: MediaNodeLike | unknown): void;
|
|
58
|
-
disconnect(): void;
|
|
59
|
-
}
|
|
60
|
-
export interface BufferLike {
|
|
61
|
-
readonly duration: number;
|
|
62
|
-
getChannelData(channel: number): Float32Array;
|
|
63
|
-
}
|
|
64
|
-
export interface SourceLike {
|
|
65
|
-
buffer: unknown;
|
|
66
|
-
connect(target: unknown): void;
|
|
67
|
-
start(when?: number): void;
|
|
68
|
-
}
|
|
69
|
-
export interface ContextLike {
|
|
70
|
-
readonly sampleRate: number;
|
|
71
|
-
readonly currentTime: number;
|
|
72
|
-
readonly destination: unknown;
|
|
73
|
-
createMediaStreamSource(stream: StreamLike): MediaNodeLike;
|
|
74
|
-
createScriptProcessor(buffer: number, inputs: number, outputs: number): MediaNodeLike & {
|
|
75
|
-
onaudioprocess: ((event: {
|
|
76
|
-
inputBuffer: BufferLike;
|
|
77
|
-
}) => void) | null;
|
|
78
|
-
};
|
|
79
|
-
createBuffer(channels: number, frames: number, rate: number): BufferLike;
|
|
80
|
-
createGain(): MediaNodeLike & {
|
|
81
|
-
readonly gain: {
|
|
82
|
-
value: number;
|
|
83
|
-
};
|
|
84
|
-
};
|
|
85
|
-
createBufferSource(): SourceLike;
|
|
86
|
-
close(): Promise<void>;
|
|
87
|
-
}
|
|
88
|
-
export interface SocketLike {
|
|
89
|
-
binaryType?: string;
|
|
90
|
-
send(data: Uint8Array): void;
|
|
91
|
-
close(): void;
|
|
92
|
-
onopen: (() => void) | null;
|
|
93
|
-
onmessage: ((event: {
|
|
94
|
-
data: unknown;
|
|
95
|
-
}) => void) | null;
|
|
96
|
-
onerror: (() => void) | null;
|
|
97
|
-
onclose: (() => void) | null;
|
|
98
|
-
}
|
|
99
|
-
/** Everything this plugin touches outside itself, injectable so every path is testable. */
|
|
100
|
-
export interface ClientAudioDeps {
|
|
101
|
-
readonly location: LocationLike | undefined;
|
|
102
|
-
readonly getUserMedia: ((constraints: unknown) => Promise<StreamLike>) | undefined;
|
|
103
|
-
readonly createAudioContext: ((sampleRate: number) => ContextLike) | undefined;
|
|
104
|
-
readonly createSocket: ((url: string) => SocketLike) | undefined;
|
|
105
|
-
readonly injected: {
|
|
106
|
-
readonly path?: string;
|
|
107
|
-
} | undefined;
|
|
108
|
-
}
|
|
109
|
-
/** What the caller — or a test — gets to see. */
|
|
110
|
-
export type ClientAudioState = {
|
|
111
|
-
readonly kind: 'idle';
|
|
112
|
-
} | {
|
|
113
|
-
readonly kind: 'live';
|
|
114
|
-
} | {
|
|
115
|
-
readonly kind: 'failed';
|
|
116
|
-
readonly reason: string;
|
|
117
|
-
};
|
|
118
|
-
export interface ClientAudio {
|
|
119
|
-
/** Acquire the microphone and connect. Resolves with the state it reached. */
|
|
120
|
-
start(): Promise<ClientAudioState>;
|
|
121
|
-
/** Release everything. Safe to call when not started. */
|
|
122
|
-
stop(): void;
|
|
123
|
-
/** Current state. */
|
|
124
|
-
state(): ClientAudioState;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* The socket URL for the host route.
|
|
128
|
-
*
|
|
129
|
-
* @param location - the page's location, or undefined when there is none.
|
|
130
|
-
* @param path - the route pathname.
|
|
131
|
-
* @returns the URL, or undefined when this page cannot host a socket at all.
|
|
132
|
-
*/
|
|
133
|
-
export declare function socketUrl(location: LocationLike | undefined, path: string): string | undefined;
|
|
134
|
-
/**
|
|
135
|
-
* Convert one captured float block to the wire's PCM16.
|
|
136
|
-
*
|
|
137
|
-
* Clamped, not wrapped: a sample above 1.0 is a loud peak, and letting it wrap turns a loud voice into
|
|
138
|
-
* noise. Asymmetric on purpose — 32767 is the largest Int16 and -32768 the smallest, so scaling both by the
|
|
139
|
-
* same factor would clip every negative peak one step early.
|
|
140
|
-
*
|
|
141
|
-
* @param input - samples in the range [-1, 1].
|
|
142
|
-
* @returns the same samples as little-endian PCM16 bytes.
|
|
143
|
-
*/
|
|
144
|
-
export declare function pcm16FromFloat32(input: Float32Array): Int16Array;
|
|
145
|
-
/**
|
|
146
|
-
* Read one PCM16 frame as playback samples.
|
|
147
|
-
*
|
|
148
|
-
* @param bytes - the frame.
|
|
149
|
-
* @returns samples in [-1, 1).
|
|
150
|
-
*/
|
|
151
|
-
export declare function float32FromPcm16(bytes: Uint8Array): Float32Array;
|
|
152
|
-
export interface ScopeLike {
|
|
153
|
-
location?: LocationLike;
|
|
154
|
-
navigator?: {
|
|
155
|
-
mediaDevices?: {
|
|
156
|
-
getUserMedia(constraints: unknown): Promise<StreamLike>;
|
|
157
|
-
};
|
|
158
|
-
};
|
|
159
|
-
AudioContext?: new (options: {
|
|
160
|
-
sampleRate: number;
|
|
161
|
-
}) => ContextLike;
|
|
162
|
-
WebSocket?: new (url: string) => SocketLike;
|
|
163
|
-
__DSH_REALTIME_AUDIO__?: {
|
|
164
|
-
readonly path?: string;
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Read the real browser APIs, and any settings the host injected.
|
|
169
|
-
*
|
|
170
|
-
* @param scope - the global scope, injectable so both the present and absent cases are testable without
|
|
171
|
-
* mutating the process's own globals.
|
|
172
|
-
* @returns the production dependencies. Every one may be absent, which is why `start` reports rather than
|
|
173
|
-
* throws: a page without a microphone API is a fact about the page, not a defect in the caller.
|
|
174
|
-
*/
|
|
175
|
-
export declare function defaultDeps(scope?: ScopeLike): ClientAudioDeps;
|
|
176
|
-
/**
|
|
177
|
-
* The client: one microphone in, one socket out, one speaker fed.
|
|
178
|
-
*
|
|
179
|
-
* @param deps - the outside world, injected so every path is testable.
|
|
180
|
-
* @returns the start/stop/state handle.
|
|
181
|
-
*/
|
|
182
|
-
export declare function createAudioClient(deps: ClientAudioDeps): ClientAudio;
|
|
183
|
-
/**
|
|
184
|
-
* The client plugin. Publishes the client on a global and releases it with the plugin.
|
|
185
|
-
*
|
|
186
|
-
* There is no UI surface yet, so a global is how it is driven — a settings card is its own increment and a
|
|
187
|
-
* bigger one than this. `inject` is empty for the same reason: nothing here needs another plugin.
|
|
188
|
-
*
|
|
189
|
-
* @param ctx - the client context, used only to own the lifetime.
|
|
190
|
-
*/
|
|
191
|
-
export declare function apply(ctx: ClientContext): void;
|
|
192
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
package/lib/client/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|