@talqing/react 0.4.0
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 +21 -0
- package/README.md +170 -0
- package/dist/cjs/images.d.ts +17 -0
- package/dist/cjs/images.d.ts.map +1 -0
- package/dist/cjs/images.js +68 -0
- package/dist/cjs/images.js.map +1 -0
- package/dist/cjs/index.d.ts +10 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +64 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/media.d.ts +20 -0
- package/dist/cjs/media.d.ts.map +1 -0
- package/dist/cjs/media.js +46 -0
- package/dist/cjs/media.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/rpc.d.ts +17 -0
- package/dist/cjs/rpc.d.ts.map +1 -0
- package/dist/cjs/rpc.js +48 -0
- package/dist/cjs/rpc.js.map +1 -0
- package/dist/cjs/session.d.ts +77 -0
- package/dist/cjs/session.d.ts.map +1 -0
- package/dist/cjs/session.js +55 -0
- package/dist/cjs/session.js.map +1 -0
- package/dist/cjs/userdata.d.ts +10 -0
- package/dist/cjs/userdata.d.ts.map +1 -0
- package/dist/cjs/userdata.js +24 -0
- package/dist/cjs/userdata.js.map +1 -0
- package/dist/esm/images.d.ts +17 -0
- package/dist/esm/images.d.ts.map +1 -0
- package/dist/esm/images.js +65 -0
- package/dist/esm/images.js.map +1 -0
- package/dist/esm/index.d.ts +10 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +35 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/media.d.ts +20 -0
- package/dist/esm/media.d.ts.map +1 -0
- package/dist/esm/media.js +42 -0
- package/dist/esm/media.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/rpc.d.ts +17 -0
- package/dist/esm/rpc.d.ts.map +1 -0
- package/dist/esm/rpc.js +44 -0
- package/dist/esm/rpc.js.map +1 -0
- package/dist/esm/session.d.ts +77 -0
- package/dist/esm/session.d.ts.map +1 -0
- package/dist/esm/session.js +50 -0
- package/dist/esm/session.js.map +1 -0
- package/dist/esm/userdata.d.ts +10 -0
- package/dist/esm/userdata.d.ts.map +1 -0
- package/dist/esm/userdata.js +21 -0
- package/dist/esm/userdata.js.map +1 -0
- package/package.json +73 -0
- package/src/images.ts +97 -0
- package/src/index.ts +58 -0
- package/src/media.ts +77 -0
- package/src/rpc.ts +61 -0
- package/src/session.tsx +148 -0
- package/src/userdata.ts +27 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useTalqingSession = useTalqingSession;
|
|
5
|
+
exports.TalqingSessionProvider = TalqingSessionProvider;
|
|
6
|
+
exports.useTalqingConnection = useTalqingConnection;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const livekit_client_1 = require("livekit-client");
|
|
10
|
+
const components_react_1 = require("@livekit/components-react");
|
|
11
|
+
const client_1 = require("@talqing/client");
|
|
12
|
+
/** One session, one call — `start()` it when this mounts and `end()` it on the
|
|
13
|
+
* way out, the lifecycle LiveKit's own session docs describe. A second call is
|
|
14
|
+
* a second mount, so give the component holding this a `key` that changes per
|
|
15
|
+
* call. Starting a finished session again would rejoin the room the last call
|
|
16
|
+
* used, which the API refuses. */
|
|
17
|
+
function useTalqingSession(options) {
|
|
18
|
+
const { token, fetchToken, client, agentId, callOptions, roomOptions } = options;
|
|
19
|
+
const [warnings, setWarnings] = (0, react_1.useState)([]);
|
|
20
|
+
// Reads every branch's fields so the dependency list is the same length on
|
|
21
|
+
// each; all but one are `undefined` on any given call.
|
|
22
|
+
const mint = (0, react_1.useCallback)(async () => {
|
|
23
|
+
if (token)
|
|
24
|
+
return token;
|
|
25
|
+
if (fetchToken)
|
|
26
|
+
return await fetchToken();
|
|
27
|
+
if (!client)
|
|
28
|
+
throw new Error("useTalqingSession needs one of token, fetchToken or client");
|
|
29
|
+
const minted = await client.calls.token({
|
|
30
|
+
tokenRequest: { ...callOptions, agent_id: agentId ?? null },
|
|
31
|
+
});
|
|
32
|
+
setWarnings(minted.warnings);
|
|
33
|
+
return { server_url: minted.server_url, participant_token: minted.participant_token };
|
|
34
|
+
}, [token, fetchToken, client, agentId, callOptions]);
|
|
35
|
+
const tokenSource = (0, react_1.useMemo)(() => (0, client_1.createTalqingTokenSource)(mint), [mint]);
|
|
36
|
+
const room = (0, react_1.useMemo)(() => new livekit_client_1.Room({ audioCaptureDefaults: client_1.TALQING_AUDIO_CAPTURE_DEFAULTS, ...roomOptions }), [roomOptions]);
|
|
37
|
+
const session = (0, components_react_1.useSession)(tokenSource, { room });
|
|
38
|
+
return (0, react_1.useMemo)(() => ({ ...session, warnings }), [session, warnings]);
|
|
39
|
+
}
|
|
40
|
+
function TalqingSessionProvider({ session, children, audio = true, }) {
|
|
41
|
+
return ((0, jsx_runtime_1.jsxs)(components_react_1.SessionProvider, { session: session, children: [children, audio ? (0, jsx_runtime_1.jsx)(components_react_1.RoomAudioRenderer, {}) : null] }));
|
|
42
|
+
}
|
|
43
|
+
/** The call itself, read from context — and `room`, which is the supported way
|
|
44
|
+
* down to raw `livekit-client` for anything this layer does not cover. */
|
|
45
|
+
function useTalqingConnection() {
|
|
46
|
+
const ctx = (0, components_react_1.useSessionContext)();
|
|
47
|
+
return {
|
|
48
|
+
isConnected: ctx.isConnected,
|
|
49
|
+
connectionState: ctx.connectionState,
|
|
50
|
+
room: ctx.room,
|
|
51
|
+
start: ctx.start,
|
|
52
|
+
end: ctx.end,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AA4Fb,8CAyBC;AAED,wDAeC;AAID,oDASC;;AAjJD,iCAA8D;AAC9D,mDAAwD;AACxD,gEAMmC;AACnC,4CAIyB;AAwEzB;;;;mCAImC;AACnC,SAAgB,iBAAiB,CAAC,OAA8B;IAC9D,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACjF,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,gBAAQ,EAAW,EAAE,CAAC,CAAC;IAEvD,2EAA2E;IAC3E,uDAAuD;IACvD,MAAM,IAAI,GAAG,IAAA,mBAAW,EAAC,KAAK,IAAqC,EAAE;QACnE,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,UAAU;YAAE,OAAO,MAAM,UAAU,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC3F,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YACtC,YAAY,EAAE,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE,OAAO,IAAI,IAAI,EAAE;SAC5D,CAAC,CAAC;QACH,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC;IACxF,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,IAAA,iCAAwB,EAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,IAAA,eAAO,EAClB,GAAG,EAAE,CACH,IAAI,qBAAI,CAAC,EAAE,oBAAoB,EAAE,uCAA8B,EAAE,GAAG,WAAW,EAAE,CAAC,EACpF,CAAC,WAAW,CAAC,CACd,CAAC;IACF,MAAM,OAAO,GAAG,IAAA,6BAAU,EAAC,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,OAAO,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,SAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,QAAQ,EACR,KAAK,GAAG,IAAI,GAKb;IACC,OAAO,CACL,wBAAC,kCAAe,IAAC,OAAO,EAAE,OAAO,aAC9B,QAAQ,EACR,KAAK,CAAC,CAAC,CAAC,uBAAC,oCAAiB,KAAG,CAAC,CAAC,CAAC,IAAI,IACrB,CACnB,CAAC;AACJ,CAAC;AAED;2EAC2E;AAC3E,SAAgB,oBAAoB;IAClC,MAAM,GAAG,GAAG,IAAA,oCAAiB,GAAE,CAAC;IAChC,OAAO;QACL,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,EAAE,GAAG,CAAC,GAAG;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type JsonObject } from "@talqing/client";
|
|
2
|
+
/** Read and write the live session's userdata from inside a provider. */
|
|
3
|
+
export declare function useTalqingUserdata(): {
|
|
4
|
+
get: (keys?: string[], responseTimeout?: number) => Promise<JsonObject>;
|
|
5
|
+
set: (patch: JsonObject, responseTimeout?: number) => Promise<{
|
|
6
|
+
ok: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=userdata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userdata.d.ts","sourceRoot":"","sources":["../../src/userdata.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAGzB,yEAAyE;AACzE,wBAAgB,kBAAkB;iBAIf,MAAM,EAAE,oBAAoB,MAAM;iBAIlC,UAAU,oBAAoB,MAAM;;;;EAOtD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useTalqingUserdata = useTalqingUserdata;
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const client_1 = require("@talqing/client");
|
|
7
|
+
const session_js_1 = require("./session.js");
|
|
8
|
+
/** Read and write the live session's userdata from inside a provider. */
|
|
9
|
+
function useTalqingUserdata() {
|
|
10
|
+
const { room } = (0, session_js_1.useTalqingConnection)();
|
|
11
|
+
return (0, react_1.useMemo)(() => ({
|
|
12
|
+
get: (keys, responseTimeout) => {
|
|
13
|
+
if (!room)
|
|
14
|
+
throw new Error("room is not connected");
|
|
15
|
+
return (0, client_1.getTalqingUserdata)(room, keys, responseTimeout);
|
|
16
|
+
},
|
|
17
|
+
set: (patch, responseTimeout) => {
|
|
18
|
+
if (!room)
|
|
19
|
+
throw new Error("room is not connected");
|
|
20
|
+
return (0, client_1.setTalqingUserdata)(room, patch, responseTimeout);
|
|
21
|
+
},
|
|
22
|
+
}), [room]);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=userdata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userdata.js","sourceRoot":"","sources":["../../src/userdata.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAWb,gDAeC;AAxBD,iCAAgC;AAChC,4CAIyB;AACzB,6CAAoD;AAEpD,yEAAyE;AACzE,SAAgB,kBAAkB;IAChC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,iCAAoB,GAAE,CAAC;IACxC,OAAO,IAAA,eAAO,EACZ,GAAG,EAAE,CAAC,CAAC;QACL,GAAG,EAAE,CAAC,IAAe,EAAE,eAAwB,EAAE,EAAE;YACjD,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACpD,OAAO,IAAA,2BAAkB,EAAC,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;QACzD,CAAC;QACD,GAAG,EAAE,CAAC,KAAiB,EAAE,eAAwB,EAAE,EAAE;YACnD,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACpD,OAAO,IAAA,2BAAkB,EAAC,IAAI,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;QAC1D,CAAC;KACF,CAAC,EACF,CAAC,IAAI,CAAC,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Room } from "livekit-client";
|
|
2
|
+
import { type TalqingSentImage } from "@talqing/client";
|
|
3
|
+
/** Send images to the agent on this call, and follow what became of each.
|
|
4
|
+
*
|
|
5
|
+
* `send` resolves once the bytes are on their way; the outcome arrives on the
|
|
6
|
+
* returned list, which is what a thumbnail should render.
|
|
7
|
+
*
|
|
8
|
+
* Takes the `Room` rather than reading it from the session context: a byte
|
|
9
|
+
* stream and an RPC handler are room-level things, and passing the room keeps
|
|
10
|
+
* this usable from a surface that manages its own connection —
|
|
11
|
+
* `useTalqingConnection().room` inside a provider, or the Room you built. */
|
|
12
|
+
export declare function useTalqingImages(room: Room | null | undefined): {
|
|
13
|
+
send: (file: File) => Promise<TalqingSentImage>;
|
|
14
|
+
sent: TalqingSentImage[];
|
|
15
|
+
clear: () => void;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=images.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/images.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;8EAQ8E;AAC9E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS;iBA4C7C,IAAI,KAAG,OAAO,CAAC,gBAAgB,CAAC;;;EAgChD"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { onTalqingImageResult, sendTalqingImage, TALQING_IMAGE_ACK_TIMEOUT_MS, } from "@talqing/client";
|
|
4
|
+
/** Send images to the agent on this call, and follow what became of each.
|
|
5
|
+
*
|
|
6
|
+
* `send` resolves once the bytes are on their way; the outcome arrives on the
|
|
7
|
+
* returned list, which is what a thumbnail should render.
|
|
8
|
+
*
|
|
9
|
+
* Takes the `Room` rather than reading it from the session context: a byte
|
|
10
|
+
* stream and an RPC handler are room-level things, and passing the room keeps
|
|
11
|
+
* this usable from a surface that manages its own connection —
|
|
12
|
+
* `useTalqingConnection().room` inside a provider, or the Room you built. */
|
|
13
|
+
export function useTalqingImages(room) {
|
|
14
|
+
const [sent, setSent] = useState([]);
|
|
15
|
+
const timers = useRef(new Map());
|
|
16
|
+
const settle = useCallback((streamId, patch) => {
|
|
17
|
+
const timer = timers.current.get(streamId);
|
|
18
|
+
if (timer) {
|
|
19
|
+
clearTimeout(timer);
|
|
20
|
+
timers.current.delete(streamId);
|
|
21
|
+
}
|
|
22
|
+
setSent((images) => images.map((image) => (image.streamId === streamId ? { ...image, ...patch } : image)));
|
|
23
|
+
}, []);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!room)
|
|
26
|
+
return;
|
|
27
|
+
return onTalqingImageResult(room, ({ streamId, ok, error }) => settle(streamId, { status: ok ? "sent" : "failed", error }));
|
|
28
|
+
}, [room, settle]);
|
|
29
|
+
const pending = timers.current;
|
|
30
|
+
useEffect(() => () => {
|
|
31
|
+
pending.forEach(clearTimeout);
|
|
32
|
+
pending.clear();
|
|
33
|
+
}, [pending]);
|
|
34
|
+
/* Each thumbnail is an object URL over the downscaled blob, and each pins that
|
|
35
|
+
blob in memory until it is revoked. This hook is mounted per call, so
|
|
36
|
+
without this every call's images would be held for the life of the tab. */
|
|
37
|
+
const previews = useRef([]);
|
|
38
|
+
useEffect(() => () => {
|
|
39
|
+
previews.current.forEach(URL.revokeObjectURL);
|
|
40
|
+
previews.current = [];
|
|
41
|
+
}, []);
|
|
42
|
+
const send = useCallback(async (file) => {
|
|
43
|
+
if (!room)
|
|
44
|
+
throw new Error("the call is not connected");
|
|
45
|
+
const image = await sendTalqingImage(room, file);
|
|
46
|
+
previews.current.push(image.previewUrl);
|
|
47
|
+
setSent((images) => [...images, image]);
|
|
48
|
+
timers.current.set(image.streamId, setTimeout(() => settle(image.streamId, {
|
|
49
|
+
status: "unknown",
|
|
50
|
+
// Four states, not two: the one people forget is the agent going
|
|
51
|
+
// away mid-upload, where no ack is ever coming.
|
|
52
|
+
error: "we did not hear back — the agent may not have received it",
|
|
53
|
+
}), TALQING_IMAGE_ACK_TIMEOUT_MS));
|
|
54
|
+
return image;
|
|
55
|
+
}, [room, settle]);
|
|
56
|
+
const clear = useCallback(() => {
|
|
57
|
+
setSent((images) => {
|
|
58
|
+
images.forEach((image) => URL.revokeObjectURL(image.previewUrl));
|
|
59
|
+
previews.current = [];
|
|
60
|
+
return [];
|
|
61
|
+
});
|
|
62
|
+
}, []);
|
|
63
|
+
return { send, sent, clear };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=images.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.js","sourceRoot":"","sources":["../../src/images.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { TalqingSessionProvider, useTalqingConnection, useTalqingSession, } from "./session.js";
|
|
2
|
+
export type { TalqingCallOptions, TalqingSession, TalqingSessionOptions, } from "./session.js";
|
|
3
|
+
export { useTalqingUserdata } from "./userdata.js";
|
|
4
|
+
export { useTalqingImages } from "./images.js";
|
|
5
|
+
export { useTalqingFrontendRpcs, useTalqingRpcHandlers } from "./rpc.js";
|
|
6
|
+
export { useTalqingAvatarTrack, useTalqingScreenShare } from "./media.js";
|
|
7
|
+
export * from "@talqing/client";
|
|
8
|
+
export { useAgent, useSessionMessages, VideoTrack, } from "@livekit/components-react";
|
|
9
|
+
export type { AgentState, ReceivedMessage, TrackReference, UseAgentReturn, UseSessionReturn, } from "@livekit/components-react";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAQ1E,cAAc,iBAAiB,CAAC;AAYhC,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,UAAU,GACX,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* React bindings for the Talqing call protocol.
|
|
2
|
+
*
|
|
3
|
+
* Thin by design. Everything here is either the call lifecycle (`useTalqingSession`
|
|
4
|
+
* and the auth union it takes) or a hook over something `@talqing/client` does to
|
|
5
|
+
* a `Room`. Nothing here wraps LiveKit to rename it: the layer only ever ADDS, so
|
|
6
|
+
* anything LiveKit can do you can do — take `useTalqingConnection().room` and use
|
|
7
|
+
* `livekit-client` directly. We never remove a capability to make our own surface
|
|
8
|
+
* look tidier, which is also why `livekit-client` and `@livekit/components-react`
|
|
9
|
+
* are peer dependencies: the `Room` we hand you is the same class your own
|
|
10
|
+
* imports and `instanceof` resolve to.
|
|
11
|
+
*/
|
|
12
|
+
export { TalqingSessionProvider, useTalqingConnection, useTalqingSession, } from "./session.js";
|
|
13
|
+
export { useTalqingUserdata } from "./userdata.js";
|
|
14
|
+
export { useTalqingImages } from "./images.js";
|
|
15
|
+
export { useTalqingFrontendRpcs, useTalqingRpcHandlers } from "./rpc.js";
|
|
16
|
+
export { useTalqingAvatarTrack, useTalqingScreenShare } from "./media.js";
|
|
17
|
+
/* All of `@talqing/client`, so one install and one import cover a web call.
|
|
18
|
+
* Everything there works against any `Room`, with or without React — the token
|
|
19
|
+
* source, the userdata and image and frontend-RPC calls, and the measured
|
|
20
|
+
* capture constants. Re-exported wholesale rather than as a curated list
|
|
21
|
+
* because the whole package is meant to be reachable from here, and a list
|
|
22
|
+
* would quietly fall behind it. */
|
|
23
|
+
export * from "@talqing/client";
|
|
24
|
+
/* LiveKit's own, re-exported UNDER THEIR OWN NAMES so a tenant installs one
|
|
25
|
+
* package and imports one name.
|
|
26
|
+
*
|
|
27
|
+
* Re-exporting is not wrapping: there is no surface of ours here to drift, and
|
|
28
|
+
* nothing is subtracted — `useAgent` is the ten-state discriminated union
|
|
29
|
+
* LiveKit ships, with every derived boolean, every action and
|
|
30
|
+
* `failureReasons` intact. Keeping LiveKit's names is the point: a
|
|
31
|
+
* `useTalqing`-prefixed alias would claim these as ours and hide where to read
|
|
32
|
+
* their documentation. Import them from `@livekit/components-react` instead if
|
|
33
|
+
* you prefer — it is the same module. */
|
|
34
|
+
export { useAgent, useSessionMessages, VideoTrack, } from "@livekit/components-react";
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAOtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE1E;;;;;mCAKmC;AACnC,cAAc,iBAAiB,CAAC;AAEhC;;;;;;;;;yCASyC;AACzC,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,UAAU,GACX,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type TrackReference } from "@livekit/components-react";
|
|
2
|
+
/** Share the caller's screen with the agent, on the settings that keep it
|
|
3
|
+
* legible — see `TALQING_SCREEN_SHARE_CAPTURE` for why each one is what it is. */
|
|
4
|
+
export declare function useTalqingScreenShare(): {
|
|
5
|
+
/** Whether a screen is being shared right now. */
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
/** True while the browser picker is open or the track is publishing. */
|
|
8
|
+
pending: boolean;
|
|
9
|
+
/** Opens the browser's share picker. Must be called from a user gesture. */
|
|
10
|
+
start: () => Promise<boolean | undefined> | Promise<void>;
|
|
11
|
+
/** Stops sharing. The agent is told it can no longer see on the next turn. */
|
|
12
|
+
stop: () => Promise<boolean | undefined> | Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
/** The video track to render for a video agent.
|
|
15
|
+
*
|
|
16
|
+
* Prefers the avatar worker's camera — the worker publishes on the agent's
|
|
17
|
+
* behalf, which is how it is identified — and falls back through the worker's
|
|
18
|
+
* screen share and then the agent's own tracks. */
|
|
19
|
+
export declare function useTalqingAvatarTrack(): TrackReference | undefined;
|
|
20
|
+
//# sourceMappingURL=media.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/media.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAMnC;mFACmF;AACnF,wBAAgB,qBAAqB;IAQ/B,kDAAkD;;IAElD,wEAAwE;;IAExE,4EAA4E;;IAE5E,8EAA8E;;EAKnF;AAED;;;;oDAIoD;AACpD,wBAAgB,qBAAqB,IAAI,cAAc,GAAG,SAAS,CAgClE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { ParticipantKind, Track } from "livekit-client";
|
|
4
|
+
import { useParticipantTracks, useRemoteParticipants, useTrackToggle, useVoiceAssistant, } from "@livekit/components-react";
|
|
5
|
+
import { TALQING_SCREEN_SHARE_CAPTURE, TALQING_SCREEN_SHARE_PUBLISH, } from "@talqing/client";
|
|
6
|
+
/** Share the caller's screen with the agent, on the settings that keep it
|
|
7
|
+
* legible — see `TALQING_SCREEN_SHARE_CAPTURE` for why each one is what it is. */
|
|
8
|
+
export function useTalqingScreenShare() {
|
|
9
|
+
const { toggle, enabled, pending } = useTrackToggle({
|
|
10
|
+
source: Track.Source.ScreenShare,
|
|
11
|
+
captureOptions: TALQING_SCREEN_SHARE_CAPTURE,
|
|
12
|
+
publishOptions: TALQING_SCREEN_SHARE_PUBLISH,
|
|
13
|
+
});
|
|
14
|
+
return useMemo(() => ({
|
|
15
|
+
/** Whether a screen is being shared right now. */
|
|
16
|
+
enabled,
|
|
17
|
+
/** True while the browser picker is open or the track is publishing. */
|
|
18
|
+
pending,
|
|
19
|
+
/** Opens the browser's share picker. Must be called from a user gesture. */
|
|
20
|
+
start: () => toggle(true),
|
|
21
|
+
/** Stops sharing. The agent is told it can no longer see on the next turn. */
|
|
22
|
+
stop: () => toggle(false),
|
|
23
|
+
}), [enabled, pending, toggle]);
|
|
24
|
+
}
|
|
25
|
+
/** The video track to render for a video agent.
|
|
26
|
+
*
|
|
27
|
+
* Prefers the avatar worker's camera — the worker publishes on the agent's
|
|
28
|
+
* behalf, which is how it is identified — and falls back through the worker's
|
|
29
|
+
* screen share and then the agent's own tracks. */
|
|
30
|
+
export function useTalqingAvatarTrack() {
|
|
31
|
+
const { agent } = useVoiceAssistant();
|
|
32
|
+
const remoteParticipants = useRemoteParticipants();
|
|
33
|
+
const worker = remoteParticipants.find((participant) => participant.kind === ParticipantKind.AGENT &&
|
|
34
|
+
participant.attributes["lk.publish_on_behalf"] === agent?.identity);
|
|
35
|
+
const agentTracks = useParticipantTracks([Track.Source.Camera, Track.Source.ScreenShare], agent?.identity);
|
|
36
|
+
const workerTracks = useParticipantTracks([Track.Source.Camera, Track.Source.ScreenShare], worker?.identity);
|
|
37
|
+
return (workerTracks.find((track) => track.source === Track.Source.Camera) ??
|
|
38
|
+
workerTracks.find((track) => track.source === Track.Source.ScreenShare) ??
|
|
39
|
+
agentTracks.find((track) => track.source === Track.Source.Camera) ??
|
|
40
|
+
agentTracks.find((track) => track.source === Track.Source.ScreenShare));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/media.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,KAAK,EAA0B,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,iBAAiB,GAElB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,iBAAiB,CAAC;AAEzB;mFACmF;AACnF,MAAM,UAAU,qBAAqB;IACnC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC;QAClD,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW;QAChC,cAAc,EAAE,4BAA4B;QAC5C,cAAc,EAAE,4BAA4B;KAC7C,CAAC,CAAC;IACH,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,CAAC;QACL,kDAAkD;QAClD,OAAO;QACP,wEAAwE;QACxE,OAAO;QACP,4EAA4E;QAC5E,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;QACzB,8EAA8E;QAC9E,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;KAC1B,CAAC,EACF,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAC3B,CAAC;AACJ,CAAC;AAED;;;;oDAIoD;AACpD,MAAM,UAAU,qBAAqB;IACnC,MAAM,EAAE,KAAK,EAAE,GAAG,iBAAiB,EAAE,CAAC;IACtC,MAAM,kBAAkB,GAAG,qBAAqB,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CACpC,CAAC,WAA8B,EAAE,EAAE,CACjC,WAAW,CAAC,IAAI,KAAK,eAAe,CAAC,KAAK;QAC1C,WAAW,CAAC,UAAU,CAAC,sBAAsB,CAAC,KAAK,KAAK,EAAE,QAAQ,CACrE,CAAC;IAEF,MAAM,WAAW,GAAG,oBAAoB,CACtC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAC/C,KAAK,EAAE,QAAQ,CAChB,CAAC;IACF,MAAM,YAAY,GAAG,oBAAoB,CACvC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAC/C,MAAM,EAAE,QAAQ,CACjB,CAAC;IAEF,OAAO,CACL,YAAY,CAAC,IAAI,CACf,CAAC,KAAqB,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,MAAM,CAChE;QACD,YAAY,CAAC,IAAI,CACf,CAAC,KAAqB,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,WAAW,CACrE;QACD,WAAW,CAAC,IAAI,CACd,CAAC,KAAqB,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,MAAM,CAChE;QACD,WAAW,CAAC,IAAI,CACd,CAAC,KAAqB,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,WAAW,CACrE,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type JsonValue, type TalqingRpcHandlers } from "@talqing/client";
|
|
2
|
+
/** Handle the agent's `frontend_rpc` calls into this page.
|
|
3
|
+
*
|
|
4
|
+
* Registration waits for the room to connect and is undone on unmount. Pass
|
|
5
|
+
* `enabled: false` to hold off. */
|
|
6
|
+
export declare function useTalqingRpcHandlers(handlers: TalqingRpcHandlers, enabled?: boolean): void;
|
|
7
|
+
/** The declarative alternative: register nothing, render what arrived.
|
|
8
|
+
*
|
|
9
|
+
* Keeps the latest payload per method name and always answers the agent "ok". */
|
|
10
|
+
export declare function useTalqingFrontendRpcs(enabled?: boolean): {
|
|
11
|
+
actions: Record<string, {
|
|
12
|
+
payload?: JsonValue;
|
|
13
|
+
at: number;
|
|
14
|
+
}>;
|
|
15
|
+
clear: () => void;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../src/rpc.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,kBAAkB,EAExB,MAAM,iBAAiB,CAAC;AAGzB;;;oCAGoC;AACpC,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,OAAO,UAAO,QAOjF;AAED;;kFAEkF;AAClF,wBAAgB,sBAAsB,CAAC,OAAO,UAAO;;kBAEtB,SAAS;YAAM,MAAM;;;EA+BnD"}
|
package/dist/esm/rpc.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { registerTalqingRpcHandlers, } from "@talqing/client";
|
|
4
|
+
import { useTalqingConnection } from "./session.js";
|
|
5
|
+
/** Handle the agent's `frontend_rpc` calls into this page.
|
|
6
|
+
*
|
|
7
|
+
* Registration waits for the room to connect and is undone on unmount. Pass
|
|
8
|
+
* `enabled: false` to hold off. */
|
|
9
|
+
export function useTalqingRpcHandlers(handlers, enabled = true) {
|
|
10
|
+
const { room, isConnected } = useTalqingConnection();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!enabled || !room || !isConnected)
|
|
13
|
+
return;
|
|
14
|
+
return registerTalqingRpcHandlers(room, handlers);
|
|
15
|
+
}, [enabled, handlers, isConnected, room]);
|
|
16
|
+
}
|
|
17
|
+
/** The declarative alternative: register nothing, render what arrived.
|
|
18
|
+
*
|
|
19
|
+
* Keeps the latest payload per method name and always answers the agent "ok". */
|
|
20
|
+
export function useTalqingFrontendRpcs(enabled = true) {
|
|
21
|
+
const [actions, setActions] = useState({});
|
|
22
|
+
const handlers = useMemo(() => ({
|
|
23
|
+
"*": async (data) => {
|
|
24
|
+
const payload = JSON.parse(data.payload || "{}");
|
|
25
|
+
const method = String(payload.method || "");
|
|
26
|
+
if (method) {
|
|
27
|
+
setActions((current) => ({
|
|
28
|
+
...current,
|
|
29
|
+
[method]: {
|
|
30
|
+
payload: payload.payload,
|
|
31
|
+
at: Date.now(),
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
return "ok";
|
|
36
|
+
},
|
|
37
|
+
}), []);
|
|
38
|
+
useTalqingRpcHandlers(handlers, enabled);
|
|
39
|
+
return {
|
|
40
|
+
actions,
|
|
41
|
+
clear: () => setActions({}),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=rpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/rpc.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EACL,0BAA0B,GAI3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD;;;oCAGoC;AACpC,MAAM,UAAU,qBAAqB,CAAC,QAA4B,EAAE,OAAO,GAAG,IAAI;IAChF,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,oBAAoB,EAAE,CAAC;IAErD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC9C,OAAO,0BAA0B,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;kFAEkF;AAClF,MAAM,UAAU,sBAAsB,CAAC,OAAO,GAAG,IAAI;IACnD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAEpC,EAAE,CAAC,CAAC;IAEN,MAAM,QAAQ,GAAG,OAAO,CACtB,GAAG,EAAE,CAAC,CAAC;QACL,GAAG,EAAE,KAAK,EAAE,IAA0B,EAAE,EAAE;YACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAc,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,CAAE,OAA+B,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;YACrE,IAAI,MAAM,EAAE,CAAC;gBACX,UAAU,CACR,CAAC,OAA4D,EAAE,EAAE,CAAC,CAAC;oBACjE,GAAG,OAAO;oBACV,CAAC,MAAM,CAAC,EAAE;wBACR,OAAO,EAAG,OAAmC,CAAC,OAAO;wBACrD,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;qBACf;iBACF,CAAC,CACH,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,EACF,EAAE,CACH,CAAC;IAEF,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEzC,OAAO;QACL,OAAO;QACP,KAAK,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Room, type RoomOptions } from "livekit-client";
|
|
3
|
+
import { type UseSessionReturn } from "@livekit/components-react";
|
|
4
|
+
import { type TalqingCallCredentials } from "@talqing/client";
|
|
5
|
+
import type { TalqingClient, TokenRequest } from "@talqing/sdk";
|
|
6
|
+
/** Everything about one web call except which agent runs it. Wire-shaped, like
|
|
7
|
+
* every other request type in this SDK. */
|
|
8
|
+
export type TalqingCallOptions = Omit<TokenRequest, "agent_id">;
|
|
9
|
+
type TalqingCallAuth =
|
|
10
|
+
/** Your server called `POST /v1/calls/token` and forwarded these two fields. */
|
|
11
|
+
{
|
|
12
|
+
token: TalqingCallCredentials;
|
|
13
|
+
fetchToken?: never;
|
|
14
|
+
client?: never;
|
|
15
|
+
agentId?: never;
|
|
16
|
+
callOptions?: never;
|
|
17
|
+
}
|
|
18
|
+
/** Your endpoint mints one. Called once, when the call starts. */
|
|
19
|
+
| {
|
|
20
|
+
fetchToken: () => Promise<TalqingCallCredentials>;
|
|
21
|
+
token?: never;
|
|
22
|
+
client?: never;
|
|
23
|
+
agentId?: never;
|
|
24
|
+
callOptions?: never;
|
|
25
|
+
}
|
|
26
|
+
/** Mint from the browser with a `TalqingClient` that already holds a
|
|
27
|
+
* credential. **Trusted first-party surfaces only** — an app that is
|
|
28
|
+
* same-origin with the API and signed in as a real editor, which is what our
|
|
29
|
+
* own dashboard is. If you are embedding a call widget for your customers,
|
|
30
|
+
* this is not your branch. */
|
|
31
|
+
| {
|
|
32
|
+
client: TalqingClient;
|
|
33
|
+
agentId: string | null;
|
|
34
|
+
/** `contact_key`, `userdata`, `vars` and the per-call agent selection.
|
|
35
|
+
* Only on this branch: on the other two the server passes them when it
|
|
36
|
+
* mints, which is what keeps a browser from choosing whose history to
|
|
37
|
+
* resume. */
|
|
38
|
+
callOptions?: TalqingCallOptions;
|
|
39
|
+
token?: never;
|
|
40
|
+
fetchToken?: never;
|
|
41
|
+
};
|
|
42
|
+
export type TalqingSessionOptions = TalqingCallAuth & {
|
|
43
|
+
roomOptions?: RoomOptions;
|
|
44
|
+
};
|
|
45
|
+
/** LiveKit's session, plus what resolving this call's plan complained about. */
|
|
46
|
+
export type TalqingSession = UseSessionReturn & {
|
|
47
|
+
/** An unreachable team member, a handoff into an agent that records when this
|
|
48
|
+
* one does not — resolved against state at CALL time, so it is not the list
|
|
49
|
+
* publishing returned. Empty until the token is minted.
|
|
50
|
+
*
|
|
51
|
+
* Populated on the `client` branch, which is the one where this browser is
|
|
52
|
+
* what minted. On the two server-minted branches your own server received
|
|
53
|
+
* them in the token response and this stays empty. */
|
|
54
|
+
warnings: string[];
|
|
55
|
+
};
|
|
56
|
+
/** One session, one call — `start()` it when this mounts and `end()` it on the
|
|
57
|
+
* way out, the lifecycle LiveKit's own session docs describe. A second call is
|
|
58
|
+
* a second mount, so give the component holding this a `key` that changes per
|
|
59
|
+
* call. Starting a finished session again would rejoin the room the last call
|
|
60
|
+
* used, which the API refuses. */
|
|
61
|
+
export declare function useTalqingSession(options: TalqingSessionOptions): TalqingSession;
|
|
62
|
+
export declare function TalqingSessionProvider({ session, children, audio, }: {
|
|
63
|
+
session: TalqingSession;
|
|
64
|
+
children: React.ReactNode;
|
|
65
|
+
audio?: boolean;
|
|
66
|
+
}): React.JSX.Element;
|
|
67
|
+
/** The call itself, read from context — and `room`, which is the supported way
|
|
68
|
+
* down to raw `livekit-client` for anything this layer does not cover. */
|
|
69
|
+
export declare function useTalqingConnection(): {
|
|
70
|
+
isConnected: boolean;
|
|
71
|
+
connectionState: import("livekit-client").ConnectionState;
|
|
72
|
+
room: Room;
|
|
73
|
+
start: (options?: import("@livekit/components-react").SessionConnectOptions) => Promise<void>;
|
|
74
|
+
end: () => Promise<void>;
|
|
75
|
+
};
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEhE;4CAC4C;AAC5C,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAmBhE,KAAK,eAAe;AAClB,gFAAgF;AAC9E;IACE,KAAK,EAAE,sBAAsB,CAAC;IAC9B,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB;AACH,kEAAkE;GAChE;IACE,UAAU,EAAE,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAClD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB;AACH;;;;+BAI+B;GAC7B;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;kBAGc;IACd,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,KAAK,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG;IAAE,WAAW,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC;AAEpF,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG;IAC9C;;;;;;2DAMuD;IACvD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF;;;;mCAImC;AACnC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,cAAc,CAyBhF;AAED,wBAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,QAAQ,EACR,KAAY,GACb,EAAE;IACD,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,qBAOA;AAED;2EAC2E;AAC3E,wBAAgB,oBAAoB;;;;;;EASnC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useMemo, useState } from "react";
|
|
4
|
+
import { Room } from "livekit-client";
|
|
5
|
+
import { RoomAudioRenderer, SessionProvider, useSession, useSessionContext, } from "@livekit/components-react";
|
|
6
|
+
import { createTalqingTokenSource, TALQING_AUDIO_CAPTURE_DEFAULTS, } from "@talqing/client";
|
|
7
|
+
/** One session, one call — `start()` it when this mounts and `end()` it on the
|
|
8
|
+
* way out, the lifecycle LiveKit's own session docs describe. A second call is
|
|
9
|
+
* a second mount, so give the component holding this a `key` that changes per
|
|
10
|
+
* call. Starting a finished session again would rejoin the room the last call
|
|
11
|
+
* used, which the API refuses. */
|
|
12
|
+
export function useTalqingSession(options) {
|
|
13
|
+
const { token, fetchToken, client, agentId, callOptions, roomOptions } = options;
|
|
14
|
+
const [warnings, setWarnings] = useState([]);
|
|
15
|
+
// Reads every branch's fields so the dependency list is the same length on
|
|
16
|
+
// each; all but one are `undefined` on any given call.
|
|
17
|
+
const mint = useCallback(async () => {
|
|
18
|
+
if (token)
|
|
19
|
+
return token;
|
|
20
|
+
if (fetchToken)
|
|
21
|
+
return await fetchToken();
|
|
22
|
+
if (!client)
|
|
23
|
+
throw new Error("useTalqingSession needs one of token, fetchToken or client");
|
|
24
|
+
const minted = await client.calls.token({
|
|
25
|
+
tokenRequest: { ...callOptions, agent_id: agentId ?? null },
|
|
26
|
+
});
|
|
27
|
+
setWarnings(minted.warnings);
|
|
28
|
+
return { server_url: minted.server_url, participant_token: minted.participant_token };
|
|
29
|
+
}, [token, fetchToken, client, agentId, callOptions]);
|
|
30
|
+
const tokenSource = useMemo(() => createTalqingTokenSource(mint), [mint]);
|
|
31
|
+
const room = useMemo(() => new Room({ audioCaptureDefaults: TALQING_AUDIO_CAPTURE_DEFAULTS, ...roomOptions }), [roomOptions]);
|
|
32
|
+
const session = useSession(tokenSource, { room });
|
|
33
|
+
return useMemo(() => ({ ...session, warnings }), [session, warnings]);
|
|
34
|
+
}
|
|
35
|
+
export function TalqingSessionProvider({ session, children, audio = true, }) {
|
|
36
|
+
return (_jsxs(SessionProvider, { session: session, children: [children, audio ? _jsx(RoomAudioRenderer, {}) : null] }));
|
|
37
|
+
}
|
|
38
|
+
/** The call itself, read from context — and `room`, which is the supported way
|
|
39
|
+
* down to raw `livekit-client` for anything this layer does not cover. */
|
|
40
|
+
export function useTalqingConnection() {
|
|
41
|
+
const ctx = useSessionContext();
|
|
42
|
+
return {
|
|
43
|
+
isConnected: ctx.isConnected,
|
|
44
|
+
connectionState: ctx.connectionState,
|
|
45
|
+
room: ctx.room,
|
|
46
|
+
start: ctx.start,
|
|
47
|
+
end: ctx.end,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAoB,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,iBAAiB,GAElB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,wBAAwB,EACxB,8BAA8B,GAE/B,MAAM,iBAAiB,CAAC;AAwEzB;;;;mCAImC;AACnC,MAAM,UAAU,iBAAiB,CAAC,OAA8B;IAC9D,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACjF,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAEvD,2EAA2E;IAC3E,uDAAuD;IACvD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,IAAqC,EAAE;QACnE,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,UAAU;YAAE,OAAO,MAAM,UAAU,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC3F,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YACtC,YAAY,EAAE,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE,OAAO,IAAI,IAAI,EAAE;SAC5D,CAAC,CAAC;QACH,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC;IACxF,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,OAAO,CAClB,GAAG,EAAE,CACH,IAAI,IAAI,CAAC,EAAE,oBAAoB,EAAE,8BAA8B,EAAE,GAAG,WAAW,EAAE,CAAC,EACpF,CAAC,WAAW,CAAC,CACd,CAAC;IACF,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,EACrC,OAAO,EACP,QAAQ,EACR,KAAK,GAAG,IAAI,GAKb;IACC,OAAO,CACL,MAAC,eAAe,IAAC,OAAO,EAAE,OAAO,aAC9B,QAAQ,EACR,KAAK,CAAC,CAAC,CAAC,KAAC,iBAAiB,KAAG,CAAC,CAAC,CAAC,IAAI,IACrB,CACnB,CAAC;AACJ,CAAC;AAED;2EAC2E;AAC3E,MAAM,UAAU,oBAAoB;IAClC,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,OAAO;QACL,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,EAAE,GAAG,CAAC,GAAG;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type JsonObject } from "@talqing/client";
|
|
2
|
+
/** Read and write the live session's userdata from inside a provider. */
|
|
3
|
+
export declare function useTalqingUserdata(): {
|
|
4
|
+
get: (keys?: string[], responseTimeout?: number) => Promise<JsonObject>;
|
|
5
|
+
set: (patch: JsonObject, responseTimeout?: number) => Promise<{
|
|
6
|
+
ok: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=userdata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userdata.d.ts","sourceRoot":"","sources":["../../src/userdata.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAGzB,yEAAyE;AACzE,wBAAgB,kBAAkB;iBAIf,MAAM,EAAE,oBAAoB,MAAM;iBAIlC,UAAU,oBAAoB,MAAM;;;;EAOtD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { getTalqingUserdata, setTalqingUserdata, } from "@talqing/client";
|
|
4
|
+
import { useTalqingConnection } from "./session.js";
|
|
5
|
+
/** Read and write the live session's userdata from inside a provider. */
|
|
6
|
+
export function useTalqingUserdata() {
|
|
7
|
+
const { room } = useTalqingConnection();
|
|
8
|
+
return useMemo(() => ({
|
|
9
|
+
get: (keys, responseTimeout) => {
|
|
10
|
+
if (!room)
|
|
11
|
+
throw new Error("room is not connected");
|
|
12
|
+
return getTalqingUserdata(room, keys, responseTimeout);
|
|
13
|
+
},
|
|
14
|
+
set: (patch, responseTimeout) => {
|
|
15
|
+
if (!room)
|
|
16
|
+
throw new Error("room is not connected");
|
|
17
|
+
return setTalqingUserdata(room, patch, responseTimeout);
|
|
18
|
+
},
|
|
19
|
+
}), [room]);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=userdata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userdata.js","sourceRoot":"","sources":["../../src/userdata.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,yEAAyE;AACzE,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAE,IAAI,EAAE,GAAG,oBAAoB,EAAE,CAAC;IACxC,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,CAAC;QACL,GAAG,EAAE,CAAC,IAAe,EAAE,eAAwB,EAAE,EAAE;YACjD,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACpD,OAAO,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;QACzD,CAAC;QACD,GAAG,EAAE,CAAC,KAAiB,EAAE,eAAwB,EAAE,EAAE;YACnD,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACpD,OAAO,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;QAC1D,CAAC;KACF,CAAC,EACF,CAAC,IAAI,CAAC,CACP,CAAC;AACJ,CAAC"}
|