@pmate/chat-sdk 0.1.2 → 0.1.4
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.
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class AsyncStream<T> implements AsyncIterable<T> {
|
|
2
|
+
private queue;
|
|
3
|
+
private state;
|
|
4
|
+
private errorValue;
|
|
5
|
+
private waiting;
|
|
6
|
+
private iteratorCreated;
|
|
7
|
+
push(value: T): boolean;
|
|
8
|
+
end(): void;
|
|
9
|
+
error(error: unknown): void;
|
|
10
|
+
[Symbol.asyncIterator](): AsyncIterator<T>;
|
|
11
|
+
private next;
|
|
12
|
+
private close;
|
|
13
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export class AsyncStream {
|
|
2
|
+
queue = [];
|
|
3
|
+
state = "open";
|
|
4
|
+
errorValue = null;
|
|
5
|
+
waiting = [];
|
|
6
|
+
iteratorCreated = false;
|
|
7
|
+
push(value) {
|
|
8
|
+
if (this.state !== "open") {
|
|
9
|
+
throw new Error(`AsyncStream is not writable (state=${this.state})`);
|
|
10
|
+
}
|
|
11
|
+
const waiter = this.waiting.shift();
|
|
12
|
+
if (waiter) {
|
|
13
|
+
waiter.resolve({ value, done: false });
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
this.queue.push(value);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
end() {
|
|
20
|
+
if (this.state === "closed" || this.state === "errored") {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
this.state = "ending";
|
|
24
|
+
if (this.queue.length === 0) {
|
|
25
|
+
this.close();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
error(error) {
|
|
29
|
+
if (this.state === "closed" || this.state === "errored") {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this.state = "errored";
|
|
33
|
+
this.errorValue = error;
|
|
34
|
+
const waiting = this.waiting;
|
|
35
|
+
this.waiting = [];
|
|
36
|
+
waiting.forEach((waiter) => waiter.reject(error));
|
|
37
|
+
this.close();
|
|
38
|
+
}
|
|
39
|
+
[Symbol.asyncIterator]() {
|
|
40
|
+
if (this.iteratorCreated) {
|
|
41
|
+
throw new Error("AsyncStream only supports a single consumer");
|
|
42
|
+
}
|
|
43
|
+
this.iteratorCreated = true;
|
|
44
|
+
return {
|
|
45
|
+
next: () => this.next(),
|
|
46
|
+
return: () => {
|
|
47
|
+
this.close();
|
|
48
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
49
|
+
},
|
|
50
|
+
throw: (error) => {
|
|
51
|
+
this.error(error);
|
|
52
|
+
return Promise.reject(error);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
next() {
|
|
57
|
+
if (this.state === "errored") {
|
|
58
|
+
return Promise.reject(this.errorValue);
|
|
59
|
+
}
|
|
60
|
+
if (this.queue.length > 0) {
|
|
61
|
+
const value = this.queue.shift();
|
|
62
|
+
if (this.queue.length === 0 && this.state === "ending") {
|
|
63
|
+
this.close();
|
|
64
|
+
}
|
|
65
|
+
return Promise.resolve({ value, done: false });
|
|
66
|
+
}
|
|
67
|
+
if (this.state === "ending" || this.state === "closed") {
|
|
68
|
+
this.close();
|
|
69
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
70
|
+
}
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
this.waiting.push({ resolve, reject });
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
close() {
|
|
76
|
+
if (this.state === "closed") {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.state = "closed";
|
|
80
|
+
const waiting = this.waiting;
|
|
81
|
+
this.waiting = [];
|
|
82
|
+
waiting.forEach((waiter) => waiter.resolve({ value: undefined, done: true }));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class RecorderProcessor extends AudioWorkletProcessor {
|
|
2
|
+
process(inputs) {
|
|
3
|
+
const input = inputs[0]
|
|
4
|
+
if (!input || !input[0]) {
|
|
5
|
+
return true
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const samples = input[0]
|
|
9
|
+
const pcm = new Int16Array(samples.length)
|
|
10
|
+
for (let i = 0; i < samples.length; i += 1) {
|
|
11
|
+
const sample = Math.max(-1, Math.min(1, samples[i]))
|
|
12
|
+
pcm[i] = sample < 0 ? sample * 0x8000 : sample * 0x7fff
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
this.port.postMessage({ type: "pcm", data: pcm.buffer }, [pcm.buffer])
|
|
16
|
+
return true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
registerProcessor("pmate-mic-recorder-processor", RecorderProcessor)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pmate/chat-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Cross-platform PMate chat input components, voice input primitives, and ASR helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
|
-
"build": "tsc -p tsconfig.build.json && cp src/voice/recorder-processor.js lib/recorder-processor.js",
|
|
28
|
+
"build": "tsc -p tsconfig.build.json && cp src/voice/recorder-processor.js lib/voice/recorder-processor.js",
|
|
29
29
|
"prepack": "pnpm run build",
|
|
30
30
|
"npm:publish": "pnpm run build && npm publish --access public --registry https://registry.npmjs.org/",
|
|
31
31
|
"test": "vitest run",
|
|
@@ -35,9 +35,8 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@emoji-mart/data": "^1.2.1",
|
|
37
37
|
"@emoji-mart/react": "^1.1.1",
|
|
38
|
-
"@pmate/agent-sdk": "
|
|
39
|
-
"
|
|
40
|
-
"jotai": "catalog:"
|
|
38
|
+
"@pmate/agent-sdk": "^1.1.2",
|
|
39
|
+
"jotai": "^2.16.1"
|
|
41
40
|
},
|
|
42
41
|
"peerDependencies": {
|
|
43
42
|
"react": "*",
|