@absolutejs/meeting 0.0.1-beta.4 → 0.0.1-beta.6
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/README.md +1 -1
- package/dist/emitter.d.ts +16 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +68 -35
- package/dist/manifest.d.ts +2 -0
- package/dist/manifest.js +8666 -0
- package/dist/manifest.json +247 -0
- package/dist/meeting.d.ts +18 -1
- package/dist/source.d.ts +52 -1
- package/package.json +18 -4
package/README.md
CHANGED
|
@@ -52,4 +52,4 @@ reference `MeetingSource` implementation and a test harness.
|
|
|
52
52
|
|
|
53
53
|
## License
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Business Source License 1.1 — production use is free except offering the package as a competing hosted service (see the Additional Use Grant in [LICENSE](./LICENSE)). Converts to Apache 2.0 on May 29, 2030.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny hand-rolled event emitter — a `Set` of listeners per event plus a fan-out
|
|
3
|
+
* `emit`. Deliberately not Node's `EventEmitter`: this runs in the browser too,
|
|
4
|
+
* keeps zero deps, and stays fully typed against an event map (no `any`, no
|
|
5
|
+
* `as never`). Used by the meeting core and the buffer source, and the shape the
|
|
6
|
+
* platform adapters mirror.
|
|
7
|
+
*
|
|
8
|
+
* Construct with the exhaustive list of event names so each set exists up front;
|
|
9
|
+
* the mapped type then guarantees `on`/`emit` are exhaustive over the map.
|
|
10
|
+
*/
|
|
11
|
+
export type Listener<T> = (payload: T) => void | Promise<void>;
|
|
12
|
+
export type Emitter<EventMap> = {
|
|
13
|
+
on: <K extends keyof EventMap>(event: K, handler: Listener<EventMap[K]>) => () => void;
|
|
14
|
+
emit: <K extends keyof EventMap>(event: K, payload: EventMap[K]) => void;
|
|
15
|
+
};
|
|
16
|
+
export declare const createEmitter: <EventMap>(events: readonly (keyof EventMap)[]) => Emitter<EventMap>;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { createMeeting } from "./meeting";
|
|
|
2
2
|
export type { MeetingSession, MeetingTurn, MeetingEventMap, CreateMeetingOptions, } from "./meeting";
|
|
3
3
|
export { createBufferMeetingSource } from "./bufferSource";
|
|
4
4
|
export type { BufferMeetingSourceOptions } from "./bufferSource";
|
|
5
|
-
export type { MeetingSource, MeetingSourceEventMap, MeetingParticipant, SpeakAudio, } from "./source";
|
|
5
|
+
export type { ChatMessage, MeetingCapabilities, MeetingSource, MeetingSourceEventMap, MeetingParticipant, SpeakAudio, } from "./source";
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,45 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
2
17
|
// src/meeting.ts
|
|
3
18
|
import {
|
|
4
19
|
createVoiceScribe
|
|
5
20
|
} from "@absolutejs/voice";
|
|
21
|
+
|
|
22
|
+
// src/emitter.ts
|
|
23
|
+
var createEmitter = (events) => {
|
|
24
|
+
const listeners = {};
|
|
25
|
+
for (const event of events) {
|
|
26
|
+
listeners[event] = new Set;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
emit: (event, payload) => {
|
|
30
|
+
for (const handler of listeners[event])
|
|
31
|
+
handler(payload);
|
|
32
|
+
},
|
|
33
|
+
on: (event, handler) => {
|
|
34
|
+
listeners[event].add(handler);
|
|
35
|
+
return () => {
|
|
36
|
+
listeners[event].delete(handler);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// src/meeting.ts
|
|
6
43
|
var createMeeting = async (options) => {
|
|
7
44
|
const scribe = await createVoiceScribe({
|
|
8
45
|
format: options.source.format,
|
|
@@ -14,16 +51,13 @@ var createMeeting = async (options) => {
|
|
|
14
51
|
});
|
|
15
52
|
const participants = new Map;
|
|
16
53
|
let lastSpeaker;
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
for (const handler of listeners[event])
|
|
25
|
-
handler(payload);
|
|
26
|
-
};
|
|
54
|
+
const { emit, on } = createEmitter([
|
|
55
|
+
"chat",
|
|
56
|
+
"end",
|
|
57
|
+
"error",
|
|
58
|
+
"participant",
|
|
59
|
+
"turn"
|
|
60
|
+
]);
|
|
27
61
|
const resolveParticipant = (turn) => participants.get(turn.speaker) ?? (lastSpeaker ? participants.get(lastSpeaker) : undefined);
|
|
28
62
|
scribe.on("turn", ({ turn }) => {
|
|
29
63
|
emit("turn", { turn: { ...turn, participant: resolveParticipant(turn) } });
|
|
@@ -48,21 +82,28 @@ var createMeeting = async (options) => {
|
|
|
48
82
|
if (participant)
|
|
49
83
|
lastSpeaker = participant;
|
|
50
84
|
scribe.send(chunk);
|
|
51
|
-
}), options.source.on("participant", ({ participant }) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
85
|
+
}), options.source.on("participant", ({ participant, status }) => {
|
|
86
|
+
if (status !== "left")
|
|
87
|
+
participants.set(participant.id, participant);
|
|
88
|
+
emit("participant", { participant, ...status ? { status } : {} });
|
|
89
|
+
}), options.source.on("chat", (payload) => emit("chat", payload)), options.source.on("end", ({ reason }) => void finalize(reason)), options.source.on("error", ({ error }) => emit("error", { error })));
|
|
90
|
+
const capabilities = options.source.capabilities ?? {
|
|
91
|
+
canChat: Boolean(options.source.sendChat),
|
|
92
|
+
canSpeak: Boolean(options.source.speak)
|
|
93
|
+
};
|
|
55
94
|
return {
|
|
95
|
+
capabilities,
|
|
56
96
|
getParticipants: () => [...participants.values()],
|
|
57
97
|
getTranscript: () => scribe.getTranscript().map((turn) => ({
|
|
58
98
|
...turn,
|
|
59
99
|
participant: resolveParticipant(turn)
|
|
60
100
|
})),
|
|
61
|
-
on
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
101
|
+
on,
|
|
102
|
+
sendChat: async (text, opts) => {
|
|
103
|
+
if (!options.source.sendChat) {
|
|
104
|
+
throw new Error("meeting.sendChat: this source does not implement sendChat() \u2014 the bot can't post to the call chat");
|
|
105
|
+
}
|
|
106
|
+
await options.source.sendChat(text, opts);
|
|
66
107
|
},
|
|
67
108
|
speak: async (audio) => {
|
|
68
109
|
if (!options.source.speak) {
|
|
@@ -84,25 +125,17 @@ var createMeeting = async (options) => {
|
|
|
84
125
|
var bytesPerSample = (format) => (format.encoding === "pcm_s16le" ? 2 : 1) * format.channels;
|
|
85
126
|
var createBufferMeetingSource = (options) => {
|
|
86
127
|
const chunkMs = options.chunkMs ?? 40;
|
|
87
|
-
const
|
|
88
|
-
audio
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
for (const handler of listeners[event])
|
|
95
|
-
handler(payload);
|
|
96
|
-
};
|
|
128
|
+
const { emit, on } = createEmitter([
|
|
129
|
+
"audio",
|
|
130
|
+
"chat",
|
|
131
|
+
"end",
|
|
132
|
+
"error",
|
|
133
|
+
"participant"
|
|
134
|
+
]);
|
|
97
135
|
let stopped = false;
|
|
98
136
|
return {
|
|
99
137
|
format: options.format,
|
|
100
|
-
on
|
|
101
|
-
listeners[event].add(handler);
|
|
102
|
-
return () => {
|
|
103
|
-
listeners[event].delete(handler);
|
|
104
|
-
};
|
|
105
|
-
},
|
|
138
|
+
on,
|
|
106
139
|
start: async () => {
|
|
107
140
|
for (const participant of options.participants ?? []) {
|
|
108
141
|
emit("participant", { participant });
|