@absolutejs/meeting 0.0.1-beta.1 → 0.0.1-beta.10
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/LICENSE +88 -0
- package/README.md +25 -1
- package/dist/bufferSource.d.ts +3 -0
- package/dist/emitter.d.ts +16 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +125 -35
- package/dist/manager.d.ts +36 -0
- package/dist/manifest.d.ts +28 -0
- package/dist/manifest.js +268 -0
- package/dist/manifest.json +408 -0
- package/dist/meeting.d.ts +21 -1
- package/dist/source.d.ts +58 -1
- package/package.json +70 -35
package/LICENSE
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
**Licensor:** Alex Kahn
|
|
4
|
+
|
|
5
|
+
**Licensed Work:** @absolutejs/meeting (https://github.com/absolutejs/meeting)
|
|
6
|
+
|
|
7
|
+
**Change Date:** May 29, 2030
|
|
8
|
+
|
|
9
|
+
**Change License:** Apache License, Version 2.0
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Terms
|
|
14
|
+
|
|
15
|
+
The Licensor hereby grants you the right to copy, modify, create derivative
|
|
16
|
+
works, redistribute, and make non-production use of the Licensed Work. The
|
|
17
|
+
Licensor may make an Additional Use Grant, permitting limited production use.
|
|
18
|
+
|
|
19
|
+
### Additional Use Grant
|
|
20
|
+
|
|
21
|
+
You may use the Licensed Work in production, provided your use does not include
|
|
22
|
+
any of the following:
|
|
23
|
+
|
|
24
|
+
1. **Offering a Competing Service.** You may not offer the Licensed Work, or
|
|
25
|
+
any derivative or substantial portion of it, to third parties as a hosted or
|
|
26
|
+
managed service that competes with a hosted meeting bot, meeting transcription, or meeting-intelligence service (including, but not limited to, services like Recall.ai, Fireflies, Gong, Otter, or Read.ai). This includes any
|
|
27
|
+
product whose primary value to its users is the functionality the Licensed
|
|
28
|
+
Work provides.
|
|
29
|
+
|
|
30
|
+
2. **Resale or Redistribution as a Standalone Product.** You may not sell,
|
|
31
|
+
license, or distribute the Licensed Work, or any derivative or fork of it,
|
|
32
|
+
as a standalone commercial product.
|
|
33
|
+
|
|
34
|
+
3. **Removal of Attribution.** Any derivative work, fork, or redistribution of
|
|
35
|
+
the Licensed Work must prominently credit AbsoluteJS and include a link to
|
|
36
|
+
the original project repository (https://github.com/absolutejs/meeting).
|
|
37
|
+
|
|
38
|
+
For clarity, the following uses are expressly permitted:
|
|
39
|
+
|
|
40
|
+
- Using the Licensed Work to build and operate your own applications, websites,
|
|
41
|
+
internal tools, or SaaS products (whether commercial or non-commercial), so
|
|
42
|
+
long as the Licensed Work itself is not the primary product you are selling.
|
|
43
|
+
- Using the Licensed Work as a dependency in commercial software you build and
|
|
44
|
+
sell, as long as the software is not itself a competing managed service of
|
|
45
|
+
the kind described in clause 1.
|
|
46
|
+
- Providing consulting, development, or professional services to clients using
|
|
47
|
+
the Licensed Work.
|
|
48
|
+
- Forking and modifying the Licensed Work for your own internal use, provided
|
|
49
|
+
attribution is maintained.
|
|
50
|
+
|
|
51
|
+
### Change Date and Change License
|
|
52
|
+
|
|
53
|
+
On the Change Date specified above, or on such other date as the Licensor may
|
|
54
|
+
specify by written notice, the Licensed Work will be made available under the
|
|
55
|
+
Change License (Apache License, Version 2.0). Until the Change Date, the terms
|
|
56
|
+
of this Business Source License 1.1 apply.
|
|
57
|
+
|
|
58
|
+
### Trademark
|
|
59
|
+
|
|
60
|
+
This license does not grant you any rights to use the "AbsoluteJS" or
|
|
61
|
+
"@absolutejs" name, logo, or any related trademarks. Forks and derivative works
|
|
62
|
+
must not be named or branded in a manner that suggests endorsement by or
|
|
63
|
+
affiliation with AbsoluteJS or the Licensor.
|
|
64
|
+
|
|
65
|
+
### Notices
|
|
66
|
+
|
|
67
|
+
You must not remove or obscure any licensing, copyright, or other notices
|
|
68
|
+
included in the Licensed Work.
|
|
69
|
+
|
|
70
|
+
### No Warranty
|
|
71
|
+
|
|
72
|
+
THE LICENSED WORK IS PROVIDED "AS IS". THE LICENSOR HEREBY DISCLAIMS ALL
|
|
73
|
+
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
|
74
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO
|
|
75
|
+
EVENT SHALL THE LICENSOR BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY,
|
|
76
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR
|
|
77
|
+
IN CONNECTION WITH THE LICENSED WORK OR THE USE OR OTHER DEALINGS IN THE
|
|
78
|
+
LICENSED WORK.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Contact
|
|
83
|
+
|
|
84
|
+
For commercial licensing inquiries or additional permissions, contact:
|
|
85
|
+
|
|
86
|
+
- **Alex Kahn**
|
|
87
|
+
- alexkahndev@gmail.com
|
|
88
|
+
- alexkahndev.github.io
|
package/README.md
CHANGED
|
@@ -37,6 +37,28 @@ await meeting.start(); // bot joins the call
|
|
|
37
37
|
// ... later: await meeting.stop()
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
For an application that joins dynamic calls, bind provider configuration once
|
|
41
|
+
and use the multi-session manager. Installation itself never contacts a meeting
|
|
42
|
+
platform:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { createMeetingManager } from "@absolutejs/meeting";
|
|
46
|
+
import { createRecallMeetingSourceFactory } from "@absolutejs/meeting-recall";
|
|
47
|
+
|
|
48
|
+
const meetings = createMeetingManager({
|
|
49
|
+
source: createRecallMeetingSourceFactory({
|
|
50
|
+
apiKey: process.env.RECALL_API_KEY!,
|
|
51
|
+
websocketUrl: "wss://app.example.com/meeting/audio",
|
|
52
|
+
}),
|
|
53
|
+
stt: deepgram({ apiKey: process.env.DEEPGRAM_API_KEY!, diarize: true }),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
await meetings.start({
|
|
57
|
+
sessionId: "deal-123",
|
|
58
|
+
target: "https://meet.google.com/abc-defg-hij",
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
40
62
|
### Testing without a platform
|
|
41
63
|
|
|
42
64
|
`createBufferMeetingSource` streams an in-memory PCM buffer in real time — the
|
|
@@ -46,10 +68,12 @@ reference `MeetingSource` implementation and a test harness.
|
|
|
46
68
|
|
|
47
69
|
- `createMeeting(options)` → `MeetingSession` (`on`, `start`, `stop`,
|
|
48
70
|
`getTranscript`, `getParticipants`).
|
|
71
|
+
- `createMeetingManager(options)` → dynamic, idempotent multi-session host
|
|
72
|
+
boundary (`start`, `stop`, `get`, `list`).
|
|
49
73
|
- `createBufferMeetingSource(options)` → `MeetingSource`.
|
|
50
74
|
- Types: `MeetingSource`, `MeetingSourceEventMap`, `MeetingParticipant`,
|
|
51
75
|
`MeetingSession`, `MeetingTurn`, `CreateMeetingOptions`.
|
|
52
76
|
|
|
53
77
|
## License
|
|
54
78
|
|
|
55
|
-
|
|
79
|
+
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.
|
package/dist/bufferSource.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AudioFormat } from "@absolutejs/voice";
|
|
2
2
|
import type { MeetingParticipant, MeetingSource } from "./source";
|
|
3
|
+
import type { MeetingSourceFactory } from "./manager";
|
|
3
4
|
export type BufferMeetingSourceOptions = {
|
|
4
5
|
format: AudioFormat;
|
|
5
6
|
/** Raw audio matching `format` (e.g. pcm_s16le bytes). */
|
|
@@ -15,3 +16,5 @@ export type BufferMeetingSourceOptions = {
|
|
|
15
16
|
* the reference implementation of `MeetingSource` for adapter authors.
|
|
16
17
|
*/
|
|
17
18
|
export declare const createBufferMeetingSource: (options: BufferMeetingSourceOptions) => MeetingSource;
|
|
19
|
+
/** Build a fresh buffer source for every managed meeting session. */
|
|
20
|
+
export declare const createBufferMeetingSourceFactory: (options: BufferMeetingSourceOptions) => MeetingSourceFactory;
|
|
@@ -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
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { createMeeting } from "./meeting";
|
|
2
2
|
export type { MeetingSession, MeetingTurn, MeetingEventMap, CreateMeetingOptions, } from "./meeting";
|
|
3
|
-
export {
|
|
3
|
+
export { createMeetingManager } from "./manager";
|
|
4
|
+
export type { ManagedMeeting, MeetingManager, MeetingManagerOptions, MeetingSourceFactory, MeetingSourceFactoryInput, } from "./manager";
|
|
5
|
+
export { createBufferMeetingSource, createBufferMeetingSourceFactory, } from "./bufferSource";
|
|
4
6
|
export type { BufferMeetingSourceOptions } from "./bufferSource";
|
|
5
|
-
export type { MeetingSource, MeetingSourceEventMap, MeetingParticipant, SpeakAudio, } from "./source";
|
|
7
|
+
export type { ChatMessage, MeetingCapabilities, MeetingSource, MeetingSourceEventMap, MeetingParticipant, SpeakAudio, } from "./source";
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
import {
|
|
4
4
|
createVoiceScribe
|
|
5
5
|
} from "@absolutejs/voice";
|
|
6
|
+
|
|
7
|
+
// src/emitter.ts
|
|
8
|
+
var createEmitter = (events) => {
|
|
9
|
+
const listeners = {};
|
|
10
|
+
for (const event of events) {
|
|
11
|
+
listeners[event] = new Set;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
emit: (event, payload) => {
|
|
15
|
+
for (const handler of listeners[event])
|
|
16
|
+
handler(payload);
|
|
17
|
+
},
|
|
18
|
+
on: (event, handler) => {
|
|
19
|
+
listeners[event].add(handler);
|
|
20
|
+
return () => {
|
|
21
|
+
listeners[event].delete(handler);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// src/meeting.ts
|
|
6
28
|
var createMeeting = async (options) => {
|
|
7
29
|
const scribe = await createVoiceScribe({
|
|
8
30
|
format: options.source.format,
|
|
@@ -14,16 +36,13 @@ var createMeeting = async (options) => {
|
|
|
14
36
|
});
|
|
15
37
|
const participants = new Map;
|
|
16
38
|
let lastSpeaker;
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
for (const handler of listeners[event])
|
|
25
|
-
handler(payload);
|
|
26
|
-
};
|
|
39
|
+
const { emit, on } = createEmitter([
|
|
40
|
+
"chat",
|
|
41
|
+
"end",
|
|
42
|
+
"error",
|
|
43
|
+
"participant",
|
|
44
|
+
"turn"
|
|
45
|
+
]);
|
|
27
46
|
const resolveParticipant = (turn) => participants.get(turn.speaker) ?? (lastSpeaker ? participants.get(lastSpeaker) : undefined);
|
|
28
47
|
scribe.on("turn", ({ turn }) => {
|
|
29
48
|
emit("turn", { turn: { ...turn, participant: resolveParticipant(turn) } });
|
|
@@ -48,21 +67,28 @@ var createMeeting = async (options) => {
|
|
|
48
67
|
if (participant)
|
|
49
68
|
lastSpeaker = participant;
|
|
50
69
|
scribe.send(chunk);
|
|
51
|
-
}), options.source.on("participant", ({ participant }) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
70
|
+
}), options.source.on("participant", ({ participant, status }) => {
|
|
71
|
+
if (status !== "left")
|
|
72
|
+
participants.set(participant.id, participant);
|
|
73
|
+
emit("participant", { participant, ...status ? { status } : {} });
|
|
74
|
+
}), options.source.on("chat", (payload) => emit("chat", payload)), options.source.on("end", ({ reason }) => void finalize(reason)), options.source.on("error", ({ error }) => emit("error", { error })));
|
|
75
|
+
const capabilities = options.source.capabilities ?? {
|
|
76
|
+
canChat: Boolean(options.source.sendChat),
|
|
77
|
+
canSpeak: Boolean(options.source.speak)
|
|
78
|
+
};
|
|
55
79
|
return {
|
|
80
|
+
capabilities,
|
|
56
81
|
getParticipants: () => [...participants.values()],
|
|
57
82
|
getTranscript: () => scribe.getTranscript().map((turn) => ({
|
|
58
83
|
...turn,
|
|
59
84
|
participant: resolveParticipant(turn)
|
|
60
85
|
})),
|
|
61
|
-
on
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
86
|
+
on,
|
|
87
|
+
sendChat: async (text, opts) => {
|
|
88
|
+
if (!options.source.sendChat) {
|
|
89
|
+
throw new Error("meeting.sendChat: this source does not implement sendChat() \u2014 the bot can't post to the call chat");
|
|
90
|
+
}
|
|
91
|
+
await options.source.sendChat(text, opts);
|
|
66
92
|
},
|
|
67
93
|
speak: async (audio) => {
|
|
68
94
|
if (!options.source.speak) {
|
|
@@ -70,6 +96,9 @@ var createMeeting = async (options) => {
|
|
|
70
96
|
}
|
|
71
97
|
await options.source.speak(audio);
|
|
72
98
|
},
|
|
99
|
+
stopSpeaking: async () => {
|
|
100
|
+
await options.source.stopSpeaking?.();
|
|
101
|
+
},
|
|
73
102
|
start: () => options.source.start(),
|
|
74
103
|
stop: async (reason) => {
|
|
75
104
|
await options.source.stop(reason);
|
|
@@ -77,29 +106,87 @@ var createMeeting = async (options) => {
|
|
|
77
106
|
}
|
|
78
107
|
};
|
|
79
108
|
};
|
|
109
|
+
// src/manager.ts
|
|
110
|
+
var createMeetingManager = (options) => {
|
|
111
|
+
const active = new Map;
|
|
112
|
+
const pending = new Map;
|
|
113
|
+
const start = async (input) => {
|
|
114
|
+
const existing = active.get(input.sessionId);
|
|
115
|
+
if (existing !== undefined) {
|
|
116
|
+
if (existing.target !== input.target) {
|
|
117
|
+
throw new Error(`meeting session ${input.sessionId} is already bound to a different target`);
|
|
118
|
+
}
|
|
119
|
+
return existing.meeting;
|
|
120
|
+
}
|
|
121
|
+
const inFlight = pending.get(input.sessionId);
|
|
122
|
+
if (inFlight !== undefined) {
|
|
123
|
+
if (inFlight.target !== input.target) {
|
|
124
|
+
throw new Error(`meeting session ${input.sessionId} is already being created for a different target`);
|
|
125
|
+
}
|
|
126
|
+
return inFlight.promise;
|
|
127
|
+
}
|
|
128
|
+
const create = (async () => {
|
|
129
|
+
const source = await options.source(input);
|
|
130
|
+
const meeting = await createMeeting({
|
|
131
|
+
...options.languageStrategy !== undefined ? { languageStrategy: options.languageStrategy } : {},
|
|
132
|
+
...options.lexicon !== undefined ? { lexicon: options.lexicon } : {},
|
|
133
|
+
...options.phraseHints !== undefined ? { phraseHints: options.phraseHints } : {},
|
|
134
|
+
sessionId: input.sessionId,
|
|
135
|
+
source,
|
|
136
|
+
stt: options.stt
|
|
137
|
+
});
|
|
138
|
+
active.set(input.sessionId, {
|
|
139
|
+
meeting,
|
|
140
|
+
sessionId: input.sessionId,
|
|
141
|
+
target: input.target
|
|
142
|
+
});
|
|
143
|
+
meeting.on("end", () => {
|
|
144
|
+
active.delete(input.sessionId);
|
|
145
|
+
});
|
|
146
|
+
try {
|
|
147
|
+
await meeting.start();
|
|
148
|
+
} catch (error) {
|
|
149
|
+
active.delete(input.sessionId);
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
return meeting;
|
|
153
|
+
})();
|
|
154
|
+
pending.set(input.sessionId, { promise: create, target: input.target });
|
|
155
|
+
try {
|
|
156
|
+
return await create;
|
|
157
|
+
} finally {
|
|
158
|
+
pending.delete(input.sessionId);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
get: (sessionId) => active.get(sessionId)?.meeting,
|
|
163
|
+
list: () => [...active.values()],
|
|
164
|
+
start,
|
|
165
|
+
stop: async (sessionId, reason) => {
|
|
166
|
+
const managed = active.get(sessionId);
|
|
167
|
+
if (managed === undefined)
|
|
168
|
+
return false;
|
|
169
|
+
await managed.meeting.stop(reason);
|
|
170
|
+
active.delete(sessionId);
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
};
|
|
80
175
|
// src/bufferSource.ts
|
|
81
176
|
var bytesPerSample = (format) => (format.encoding === "pcm_s16le" ? 2 : 1) * format.channels;
|
|
82
177
|
var createBufferMeetingSource = (options) => {
|
|
83
178
|
const chunkMs = options.chunkMs ?? 40;
|
|
84
|
-
const
|
|
85
|
-
audio
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
for (const handler of listeners[event])
|
|
92
|
-
handler(payload);
|
|
93
|
-
};
|
|
179
|
+
const { emit, on } = createEmitter([
|
|
180
|
+
"audio",
|
|
181
|
+
"chat",
|
|
182
|
+
"end",
|
|
183
|
+
"error",
|
|
184
|
+
"participant"
|
|
185
|
+
]);
|
|
94
186
|
let stopped = false;
|
|
95
187
|
return {
|
|
96
188
|
format: options.format,
|
|
97
|
-
on
|
|
98
|
-
listeners[event].add(handler);
|
|
99
|
-
return () => {
|
|
100
|
-
listeners[event].delete(handler);
|
|
101
|
-
};
|
|
102
|
-
},
|
|
189
|
+
on,
|
|
103
190
|
start: async () => {
|
|
104
191
|
for (const participant of options.participants ?? []) {
|
|
105
192
|
emit("participant", { participant });
|
|
@@ -120,7 +207,10 @@ var createBufferMeetingSource = (options) => {
|
|
|
120
207
|
}
|
|
121
208
|
};
|
|
122
209
|
};
|
|
210
|
+
var createBufferMeetingSourceFactory = (options) => () => createBufferMeetingSource(options);
|
|
123
211
|
export {
|
|
212
|
+
createMeetingManager,
|
|
124
213
|
createMeeting,
|
|
214
|
+
createBufferMeetingSourceFactory,
|
|
125
215
|
createBufferMeetingSource
|
|
126
216
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CreateMeetingOptions, MeetingSession } from "./meeting";
|
|
2
|
+
import type { MeetingSource } from "./source";
|
|
3
|
+
export type MeetingSourceFactoryInput = {
|
|
4
|
+
/** Stable host-owned identity used for tracing, idempotency, and storage. */
|
|
5
|
+
sessionId: string;
|
|
6
|
+
/**
|
|
7
|
+
* Adapter-defined call target. Recall uses a Meet/Zoom/Teams URL; Discord
|
|
8
|
+
* uses a voice-channel id. The core deliberately does not interpret it.
|
|
9
|
+
*/
|
|
10
|
+
target: string;
|
|
11
|
+
};
|
|
12
|
+
export type MeetingSourceFactory = (input: MeetingSourceFactoryInput) => MeetingSource | Promise<MeetingSource>;
|
|
13
|
+
export type MeetingManagerOptions = Omit<CreateMeetingOptions, "sessionId" | "source"> & {
|
|
14
|
+
source: MeetingSourceFactory;
|
|
15
|
+
};
|
|
16
|
+
export type ManagedMeeting = {
|
|
17
|
+
meeting: MeetingSession;
|
|
18
|
+
sessionId: string;
|
|
19
|
+
target: string;
|
|
20
|
+
};
|
|
21
|
+
export type MeetingManager = {
|
|
22
|
+
/**
|
|
23
|
+
* Create and join one meeting. Session ids are unique while active; callers
|
|
24
|
+
* retrying the same id receive the existing session without joining twice.
|
|
25
|
+
*/
|
|
26
|
+
start(input: MeetingSourceFactoryInput): Promise<MeetingSession>;
|
|
27
|
+
get(sessionId: string): MeetingSession | undefined;
|
|
28
|
+
list(): ManagedMeeting[];
|
|
29
|
+
stop(sessionId: string, reason?: string): Promise<boolean>;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Multi-session host boundary for dynamic meeting targets. It keeps provider
|
|
33
|
+
* configuration in the source factory and accepts only the per-call target
|
|
34
|
+
* and stable session identity at execution time.
|
|
35
|
+
*/
|
|
36
|
+
export declare const createMeetingManager: (options: MeetingManagerOptions) => MeetingManager;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { MeetingManager, MeetingManagerOptions } from "./manager";
|
|
2
|
+
export declare const manifest: Omit<import("@absolutejs/manifest").PackageManifest<MeetingManagerOptions, MeetingManager>, "contract" | "settings" | "tools"> & (({
|
|
3
|
+
contract: 1;
|
|
4
|
+
tools?: Record<string, import("@absolutejs/manifest").LegacyManifestTool<MeetingManager>> | undefined;
|
|
5
|
+
} | {
|
|
6
|
+
contract: 2;
|
|
7
|
+
tools?: Record<string, import("@absolutejs/manifest").AuthorizedManifestTool<MeetingManager>> | undefined;
|
|
8
|
+
}) & {
|
|
9
|
+
settings: import("@sinclair/typebox").TObject<{
|
|
10
|
+
languageStrategy: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
11
|
+
allowedLanguages: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
12
|
+
mode: import("@sinclair/typebox").TLiteral<"auto-detect">;
|
|
13
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
14
|
+
mode: import("@sinclair/typebox").TLiteral<"fixed">;
|
|
15
|
+
primaryLanguage: import("@sinclair/typebox").TString;
|
|
16
|
+
secondaryLanguages: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
17
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
18
|
+
mode: import("@sinclair/typebox").TLiteral<"allow-switching">;
|
|
19
|
+
primaryLanguage: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
20
|
+
secondaryLanguages: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
21
|
+
}>]>>;
|
|
22
|
+
phraseHints: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
23
|
+
aliases: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
24
|
+
boost: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
25
|
+
text: import("@sinclair/typebox").TString;
|
|
26
|
+
}>>>;
|
|
27
|
+
}>;
|
|
28
|
+
});
|