ink-framework-audio 0.1.0-alpha.12 → 0.1.0-alpha.13
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/package.json +5 -4
- package/src/capture-internal.ts +10 -19
- package/src/index.ts +9 -12
- package/src/microphone.ts +1 -1
- package/src/recording.ts +1 -1
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ink-framework-audio",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.13",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": "./src/index.ts",
|
|
6
6
|
"./microphone": "./src/microphone.ts",
|
|
7
7
|
"./recording": "./src/recording.ts"
|
|
8
8
|
},
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"@ink/files": "npm:ink-framework-files@0.1.0-alpha.
|
|
11
|
-
"ink": "npm:ink-framework@0.1.0-alpha.
|
|
10
|
+
"@ink/files": "npm:ink-framework-files@0.1.0-alpha.13",
|
|
11
|
+
"ink": "npm:ink-framework@0.1.0-alpha.13",
|
|
12
12
|
"react": "19.2.8"
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"files": [
|
|
21
21
|
"src",
|
|
22
22
|
"*.json",
|
|
23
|
-
"*.ts"
|
|
23
|
+
"*.ts",
|
|
24
|
+
"*.md"
|
|
24
25
|
]
|
|
25
26
|
}
|
package/src/capture-internal.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { createElement, useEffect, useMemo,
|
|
1
|
+
import { createElement, useEffect, useMemo, useState } from "ink/internal/react";
|
|
2
2
|
import type { Snapshot, SnapshotSource } from "ink";
|
|
3
3
|
import { NativeError } from "ink/native";
|
|
4
|
-
import {
|
|
4
|
+
import { useNativeController } from "ink/internal/controller";
|
|
5
5
|
|
|
6
6
|
const displayController = Symbol("captureController");
|
|
7
7
|
export type CaptureDisplay = { readonly [displayController]: number | null };
|
|
@@ -48,7 +48,7 @@ export function useCapture<State extends { status: string; error: Error | null }
|
|
|
48
48
|
) {
|
|
49
49
|
const [state, setState] = useState(() => selectStatus(initial));
|
|
50
50
|
const [id, setId] = useState<number | null>(null);
|
|
51
|
-
const controller =
|
|
51
|
+
const controller = useNativeController("audio", "audio capture");
|
|
52
52
|
const channel = useMemo(() => {
|
|
53
53
|
let snapshot: Snapshot<State> = { status: "loading" };
|
|
54
54
|
const listeners = new Set<() => void>();
|
|
@@ -75,7 +75,7 @@ export function useCapture<State extends { status: string; error: Error | null }
|
|
|
75
75
|
},
|
|
76
76
|
};
|
|
77
77
|
return { source, publish, observe };
|
|
78
|
-
}, []);
|
|
78
|
+
}, [controller]);
|
|
79
79
|
useEffect(() => {
|
|
80
80
|
setState(selectStatus(initial));
|
|
81
81
|
setId(null);
|
|
@@ -92,27 +92,18 @@ export function useCapture<State extends { status: string; error: Error | null }
|
|
|
92
92
|
setState({ ...selectStatus(initial), status: "error", error: failure });
|
|
93
93
|
channel.publish({ status: "error", error: failure });
|
|
94
94
|
};
|
|
95
|
-
|
|
96
|
-
if (controller.current !== attachment) return;
|
|
95
|
+
return controller.attach({ kind, config: referenceHz === undefined ? {} : { referenceHz } }, value => {
|
|
97
96
|
try { publish(decode(value)); }
|
|
98
97
|
catch (error) { fail(error); }
|
|
98
|
+
}, fail, id => {
|
|
99
|
+
setId(id);
|
|
100
|
+
channel.observe();
|
|
99
101
|
});
|
|
100
|
-
|
|
101
|
-
void attachment.ready.then(() => {
|
|
102
|
-
if (controller.current === attachment) {
|
|
103
|
-
setId(attachment.id);
|
|
104
|
-
channel.observe();
|
|
105
|
-
}
|
|
106
|
-
}, error => { if (controller.current === attachment) fail(error); });
|
|
107
|
-
return () => {
|
|
108
|
-
controller.current = null;
|
|
109
|
-
void attachment.dispose().catch(error => console.error("Could not release audio capture", error));
|
|
110
|
-
};
|
|
111
|
-
}, [kind, initial, decode, selectStatus, referenceHz, channel]);
|
|
102
|
+
}, [kind, initial, decode, selectStatus, referenceHz, channel, controller]);
|
|
112
103
|
const call = useMemo(() => async (operation: string) => {
|
|
113
104
|
if (!controller.current) throw new NativeError("unavailable", "Audio capture is not attached");
|
|
114
105
|
return controller.current.call(operation);
|
|
115
|
-
}, []);
|
|
106
|
+
}, [controller]);
|
|
116
107
|
const display = useMemo(() => ({ [displayController]: id }), [id]);
|
|
117
108
|
return { state, ready: id !== null, call, display, measurements: channel.source };
|
|
118
109
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
-
import {
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from "ink/internal/react";
|
|
2
|
+
import { useNativeController } from "ink/internal/controller";
|
|
3
3
|
import { NativeError } from "ink/native";
|
|
4
4
|
import { playbackController } from "ink/internal/playback";
|
|
5
5
|
|
|
@@ -137,24 +137,21 @@ export function usePlayer(options: PlayerOptions = {}) {
|
|
|
137
137
|
if (!Number.isSafeInteger(startupBuffer) || startupBuffer < 0 || startupBuffer > 30_000) throw new RangeError("Startup buffering must be between 0 and 30000 milliseconds");
|
|
138
138
|
const [state, setState] = useState(initial);
|
|
139
139
|
const current = useRef(initial);
|
|
140
|
-
const controller =
|
|
140
|
+
const controller = useNativeController("audio", "audio player");
|
|
141
141
|
useEffect(() => {
|
|
142
142
|
const publish = (next: PlayerState) => { current.current = next; setState(next); };
|
|
143
143
|
publish(initial);
|
|
144
|
-
const
|
|
144
|
+
const detach = controller.attach({ kind: "player", config: { session, playback: mode, usage, cache, preloadNext, startupBuffer } }, value => {
|
|
145
145
|
try { publish(decode(value)); }
|
|
146
146
|
catch (error) { publish({ ...initial, error: error instanceof Error ? error : new Error(String(error)) }); }
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
void attachment.ready.catch(error => {
|
|
150
|
-
if (controller.current === attachment) publish({ ...initial, error: error instanceof Error ? error : new Error(String(error)) });
|
|
147
|
+
}, error => {
|
|
148
|
+
publish({ ...initial, error: error instanceof Error ? error : new Error(String(error)) });
|
|
151
149
|
});
|
|
152
150
|
return () => {
|
|
153
|
-
|
|
151
|
+
detach();
|
|
154
152
|
current.current = initial;
|
|
155
|
-
void attachment.dispose().catch(error => console.error("Could not release audio player", error));
|
|
156
153
|
};
|
|
157
|
-
}, [session, mode, usage, cache, preloadNext, startupBuffer]);
|
|
154
|
+
}, [session, mode, usage, cache, preloadNext, startupBuffer, controller]);
|
|
158
155
|
const commands = useMemo(() => {
|
|
159
156
|
const call = async (operation: string, payload: unknown = {}) => {
|
|
160
157
|
if (!controller.current || !current.current.ready) throw new NativeError("unavailable", "Audio player is not ready");
|
|
@@ -224,6 +221,6 @@ export function usePlayer(options: PlayerOptions = {}) {
|
|
|
224
221
|
return call("seekTo", { value: position });
|
|
225
222
|
},
|
|
226
223
|
};
|
|
227
|
-
}, []);
|
|
224
|
+
}, [controller]);
|
|
228
225
|
return { state, [playbackController]: controller.current?.id, ...commands };
|
|
229
226
|
}
|
package/src/microphone.ts
CHANGED
package/src/recording.ts
CHANGED