UNPKG

@charisma-ai/react

Version:

Charisma.ai chat component for React

247 lines (239 loc) 9.44 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var sdk = require('@charisma-ai/sdk'); const CharismaContext = React.createContext(undefined); var __rest = (undefined && undefined.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; const useCharisma = ({ playthroughToken, charismaUrl, onConnect = () => { }, onReady = () => { }, onError = () => { }, isConnected = false }) => { const [charisma, setCharisma] = React.useState(); const onConnectRef = React.useRef(onConnect); React.useEffect(() => { onConnectRef.current = onConnect; }, [onConnect]); const onReadyRef = React.useRef(onReady); React.useEffect(() => { onReadyRef.current = onReady; }, [onReady]); const onErrorRef = React.useRef(onError); React.useEffect(() => { onErrorRef.current = onError; }, [onError]); React.useEffect(() => { if (playthroughToken) { const newCharisma = new sdk.Charisma(playthroughToken, { charismaUrl }); newCharisma.on("connect", onConnectRef.current); newCharisma.on("ready", onReadyRef.current); newCharisma.on("error", onErrorRef.current); setCharisma(newCharisma); return () => { newCharisma.cleanup(); }; } return undefined; }, [playthroughToken]); React.useEffect(() => { if (charisma) { if (isConnected) { charisma.connect(); } else { charisma.cleanup(); } } }, [isConnected, charisma]); return charisma; }; const Charisma = (_a) => { var { children } = _a, props = __rest(_a, ["children"]); const charisma = useCharisma(props); return (React__default.createElement(CharismaContext.Provider, { value: charisma || null }, typeof children === "function" ? children(charisma) : children)); }; var __rest$1 = (undefined && undefined.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; (function (ChatMode) { ChatMode["Tap"] = "tap"; ChatMode["Chat"] = "chat"; })(exports.ChatMode || (exports.ChatMode = {})); const useConversation = ({ conversationId, onChangeCharacterMoods, onMessage, onStartTyping, onStopTyping, onSceneCompleted, onStart, onReply, onTap, speechConfig, stopOnSceneComplete }) => { const charisma = React.useContext(CharismaContext); if (charisma === undefined) { throw new Error(`To use \`Conversation\`, you must wrap it within a \`Charisma\` instance.`); } const [inputValue, setInputValue] = React.useState(""); const [isTyping, setIsTyping] = React.useState(false); const [messages, setMessages] = React.useState([]); const [mode, setMode] = React.useState(exports.ChatMode.Chat); const onMessageRef = React.useRef(() => { }); const onStartTypingRef = React.useRef(() => { }); const onStopTypingRef = React.useRef(() => { }); const onSceneCompletedRef = React.useRef(() => { }); const characterMoodsRef = React.useRef({}); React.useEffect(() => { onMessageRef.current = (event) => { setMessages([...messages, event]); if (event.tapToContinue) { setMode(exports.ChatMode.Tap); } else { setMode(exports.ChatMode.Chat); } if (event.characterMoods.length > 0) { const newCharacterMoods = Object.assign({}, characterMoodsRef.current); event.characterMoods.forEach(({ id, mood }) => { newCharacterMoods[id] = mood; }); characterMoodsRef.current = newCharacterMoods; if (onChangeCharacterMoods) { onChangeCharacterMoods(newCharacterMoods); } } if (onMessage) { onMessage(event); } }; }, [onMessage, messages, onChangeCharacterMoods]); React.useEffect(() => { onStartTypingRef.current = (event) => { setIsTyping(true); if (onStartTyping) { onStartTyping(event); } }; }, [onStartTyping]); React.useEffect(() => { onStopTypingRef.current = (event) => { setIsTyping(false); if (onStopTyping) { onStopTyping(event); } }; }, [onStopTyping]); React.useEffect(() => { onSceneCompletedRef.current = (event) => { if (onSceneCompleted) { onSceneCompleted(event); } }; }, [onSceneCompleted]); const conversationRef = React.useRef(); React.useEffect(() => { if (conversationRef.current) { conversationRef.current.setSpeechConfig(speechConfig); if (typeof stopOnSceneComplete === "boolean") { conversationRef.current.setStopOnSceneEnd(stopOnSceneComplete); } } }, [speechConfig, stopOnSceneComplete]); React.useEffect(() => { (async function run() { if (charisma && conversationId) { const conversation = await charisma.joinConversation(conversationId); conversation.on("message", event => { onMessageRef.current(event); }); conversation.on("start-typing", event => onStartTypingRef.current(event)); conversation.on("stop-typing", event => onStopTypingRef.current(event)); conversation.on("scene-completed", event => onSceneCompletedRef.current(event)); conversation.setSpeechConfig(speechConfig); if (typeof stopOnSceneComplete === "boolean") { conversation.setStopOnSceneEnd(stopOnSceneComplete); } conversationRef.current = conversation; return () => { charisma.leaveConversation(conversationId); conversationRef.current = undefined; }; } return undefined; })(); }, [charisma, conversationId]); const onStartRef = React.useRef(onStart); const onReplyRef = React.useRef(onReply); const onTapRef = React.useRef(onTap); React.useEffect(() => { onStartRef.current = onStart; }, [onStart]); React.useEffect(() => { onReplyRef.current = onReply; }, [onReply]); React.useEffect(() => { onTapRef.current = onTap; }, [onTap]); const returnedValue = React.useMemo(() => { return { inputValue, isTyping, messages, mode, type: setInputValue, start: event => { if (onStartRef.current) { onStartRef.current(event || {}); } setMessages([]); if (conversationRef.current) { conversationRef.current.start(event); } }, reply: event => { if (onReplyRef.current) { onReplyRef.current(event); } setMessages([ ...messages, { type: "player", message: { text: event.text } } ]); setInputValue(""); if (conversationRef.current) { conversationRef.current.reply(event); } }, tap: () => { if (onTapRef.current) { onTapRef.current(); } if (conversationRef.current) { conversationRef.current.tap(); } } }; }, [inputValue, isTyping, messages, mode]); return returnedValue; }; const Conversation = (_a) => { var { children } = _a, props = __rest$1(_a, ["children"]); const conversation = useConversation(props); return React__default.createElement(React__default.Fragment, null, children(conversation)); }; exports.Charisma = Charisma; exports.CharismaContext = CharismaContext; exports.Conversation = Conversation; exports.useCharisma = useCharisma; exports.useConversation = useConversation; //# sourceMappingURL=index.js.map