UNPKG

@sberdevices/assistant-client

Version:

Модуль взаимодействия с виртуальным ассистентом

431 lines (413 loc) 18.7 kB
import { c as createNanoEvents, _ as __spreadArrays, a as __rest, b as __assign, p as proto } from './typings-4aa98dc6.js'; // Unique ID creation requires a high quality random # generator. In the browser we therefore // require the crypto API and do not support built-in fallback to lower quality random number // generators (like Math.random()). // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also, // find the complete implementation of crypto (msCrypto) on IE11. var getRandomValues = typeof crypto != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto != 'undefined' && typeof msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto); var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef function rng() { if (!getRandomValues) { throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); } return getRandomValues(rnds8); } /** * Convert array of 16 byte values to UUID string format of the form: * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */ var byteToHex = []; for (var i = 0; i < 256; ++i) { byteToHex[i] = (i + 0x100).toString(16).substr(1); } function bytesToUuid(buf, offset) { var i = offset || 0; var bth = byteToHex; // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 return [bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]]].join(''); } function v4(options, buf, offset) { var i = buf && offset || 0; if (typeof options == 'string') { buf = options === 'binary' ? new Array(16) : null; options = null; } options = options || {}; var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` rnds[6] = rnds[6] & 0x0f | 0x40; rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided if (buf) { for (var ii = 0; ii < 16; ++ii) { buf[i + ii] = rnds[ii]; } } return buf || bytesToUuid(rnds); } var createNanoObservable = function (observerFunc) { var _a = createNanoEvents(), on = _a.on, emit = _a.emit; var subscribe = function (_a) { var next = _a.next; var unsubscribe = on('next', next); return { unsubscribe: unsubscribe }; }; observerFunc({ next: function (data) { emit('next', data); }, }); return { subscribe: subscribe, }; }; var findCommandIndex = function (arr, command) { var _a, _b; var index = -1; if (command.type === 'character') { index = arr.findIndex(function (c) { return c.type === 'character' && c.character.id === command.character.id; }); } else if (command.type === 'insets') { index = arr.findIndex(function (c) { return c.type === 'insets'; }); } else if (command.type === 'app_context') { index = arr.findIndex(function (c) { return c.type === 'app_context'; }); } else if (command.sdk_meta && ((_a = command.sdk_meta) === null || _a === void 0 ? void 0 : _a.mid) && ((_b = command.sdk_meta) === null || _b === void 0 ? void 0 : _b.mid) !== '-1') { index = arr.findIndex(function (c) { var _a, _b; return ((_a = c.sdk_meta) === null || _a === void 0 ? void 0 : _a.mid) === ((_b = command.sdk_meta) === null || _b === void 0 ? void 0 : _b.mid); }); } return index; }; var appInitialData = (function () { var isPulled = false; var pulled = []; var committed = []; var diff = []; var isCommandWasPulled = function (command) { return findCommandIndex(pulled, command) >= 0; }; return { /** * Прочитать appInitialData * @returns Массив комманд */ pull: function () { isPulled = true; pulled = __spreadArrays((window.appInitialData || [])); return __spreadArrays(pulled); }, /** * Зафиксировать текущее состояние appInitialData */ commit: function () { committed = __spreadArrays((window.appInitialData || [])); diff = isPulled === true ? (window.appInitialData || []).filter(function (c) { return !isCommandWasPulled(c); }) : __spreadArrays((window.appInitialData || [])); }, /** * Возвращает диф appInitialData между pull и commit * @returns Массив комманд */ diff: function () { return __spreadArrays(diff); }, /** * Возвращает флаг наличия command в appInitialData на момент commit * @param command Команда, которую нужно проверить на наличие в appInitialData * @returns true - если команда была в appInitialData */ isCommitted: function (command) { var commandIndex = findCommandIndex(committed, command); var isCommitted = commandIndex >= 0; if (isCommitted) { committed.splice(commandIndex, 1); } return isCommitted; }, /** * Возвращает первое сообщение из appInitialData, подходящее под фильтры param * @param param Параметры: тип сообщения (например, smart_app_data) * и тип команды (значение поля smart_app_data.type) * @returns Первое сообщение, соответствующее параметрам или undefined */ find: function (_a) { var type = _a.type, command = _a.command; var data = __spreadArrays((window.appInitialData || [])); var result = data.find(function (data) { if (!command && type && type === data.type) { return true; } var isCommandInSmartAppData = command && 'smart_app_data' in data; if (!isCommandInSmartAppData) { return; } if (command === data.smart_app_data.command || command === data.smart_app_data.type) { return true; } return false; }); return (result && 'smart_app_data' in result ? result.smart_app_data : result); }, }; })(); var excludeTags = ['A', 'AUDIO', 'BUTTON', 'INPUT', 'OPTION', 'SELECT', 'TEXTAREA', 'VIDEO']; function inIframe() { try { return window.self !== window.top; } catch (e) { return true; } } if (typeof window !== 'undefined' && inIframe()) { var postMessage_1 = function (action) { var _a; (_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(JSON.stringify(action), '*'); }; var historyBack_1 = function () { var prevPage = window.location.href; window.history.back(); setTimeout(function () { // закрываем страницу, если переход назад не поменял урл if (window.location.href === prevPage) { postMessage_1({ type: 'close' }); } }, 500); }; window.appInitialData = []; window.AssistantHost = { sendDataContainer: function (json) { postMessage_1({ type: 'sendDataContainer', payload: json }); }, close: function () { postMessage_1({ type: 'close' }); }, sendData: function (json) { postMessage_1({ type: 'sendData', payload: json }); }, setSuggests: function (suggests) { postMessage_1({ type: 'setSuggests', payload: suggests }); }, setHints: function (hints) { postMessage_1({ type: 'setHints', payload: hints }); }, ready: function () { postMessage_1({ type: 'ready' }); }, sendText: function (message) { postMessage_1({ type: 'sendText', payload: message }); }, }; window.addEventListener('message', function (e) { var _a, _b, _c, _d, _e, _f, _g, _h; try { if (typeof e.data === 'string') { var data = JSON.parse(e.data); switch (data.type) { case 'onBack': historyBack_1(); break; case 'onData': (_b = (_a = window.AssistantClient) === null || _a === void 0 ? void 0 : _a.onData) === null || _b === void 0 ? void 0 : _b.call(_a, data.payload); break; case 'onRequestState': { var state = (_d = (_c = window.AssistantClient) === null || _c === void 0 ? void 0 : _c.onRequestState) === null || _d === void 0 ? void 0 : _d.call(_c); postMessage_1({ type: 'state', payload: state, requestId: data.requestId }); break; } case 'onRequestRecoveryState': { var recoverystate = (_f = (_e = window.AssistantClient) === null || _e === void 0 ? void 0 : _e.onRequestRecoveryState) === null || _f === void 0 ? void 0 : _f.call(_e); postMessage_1({ type: 'recoveryState', payload: recoverystate }); break; } case 'onStart': (_h = (_g = window.AssistantClient) === null || _g === void 0 ? void 0 : _g.onStart) === null || _h === void 0 ? void 0 : _h.call(_g); break; default: // eslint-disable-next-line no-console console.error(e, 'Unknown parsed message'); break; } } } catch (err) { // eslint-disable-next-line no-console console.error(err, 'Unknown message'); } }); window.addEventListener('keydown', function (_a) { var _b, _c; var code = _a.code; switch (code) { case 'Enter': if (document.activeElement && !excludeTags.includes(document.activeElement.tagName)) { (_c = (_b = document.activeElement).click) === null || _c === void 0 ? void 0 : _c.call(_b); } break; case 'Escape': historyBack_1(); break; } }); } var createAssistant = function (_a) { var _b; var getState = _a.getState, getRecoveryState = _a.getRecoveryState, _c = _a.ready, ready = _c === void 0 ? true : _c; var currentGetState = getState; var currentGetRecoveryState = getRecoveryState; var isInitialCommandsEmitted = false; var _d = createNanoEvents(), on = _d.on, emit = _d.emit; var observables = new Map(); var emitCommand = function (command) { if (command.type === 'smart_app_data') { emit('command', command.smart_app_data); } if (command.type === 'smart_app_error') { emit('error', command.smart_app_error); } return emit('data', command); }; var cancelTts = typeof ((_b = window.AssistantHost) === null || _b === void 0 ? void 0 : _b.cancelTts) !== 'undefined' ? function () { var _a, _b; (_b = (_a = window.AssistantHost).cancelTts) === null || _b === void 0 ? void 0 : _b.call(_a, ''); } : undefined; var emitAppInitialData = function () { if (!isInitialCommandsEmitted) { appInitialData.diff().forEach(function (c) { return emitCommand(c); }); isInitialCommandsEmitted = true; } }; window.AssistantClient = { onData: function (command) { var _a, _b, _c; if (appInitialData.isCommitted(command)) { return; } /// фильтр команды 'назад' /// может приходить type='system', но в типах это не отражаем // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore if (command.type === 'system' && ((_b = (_a = command.system) === null || _a === void 0 ? void 0 : _a.command) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'BACK') { return; } if ((command.type === 'smart_app_data' || command.type === 'smart_app_error') && ((_c = command.sdk_meta) === null || _c === void 0 ? void 0 : _c.requestId) && observables.has(command.sdk_meta.requestId)) { // eslint-disable-next-line @typescript-eslint/no-unused-vars var _d = command.sdk_meta, realReqId = _d.requestId, meta = __rest(_d, ["requestId"]); var _e = observables.get(command.sdk_meta.requestId) || {}, requestId = _e.requestId, next = _e.next; if (Object.keys(meta).length > 0 || requestId) { // eslint-disable-next-line @typescript-eslint/camelcase command.sdk_meta = __assign({}, meta); if (requestId) { // eslint-disable-next-line @typescript-eslint/camelcase command.sdk_meta = { requestId: requestId }; } } if (next) { next(command.type === 'smart_app_data' ? command : command); } return; } emitCommand(command); }, onRequestState: function () { return currentGetState(); }, onRequestRecoveryState: function () { if (currentGetRecoveryState) { return currentGetRecoveryState(); } return undefined; }, onStart: function () { emit('start'); emitAppInitialData(); }, }; var readyFn = function () { var _a; appInitialData.commit(); (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.ready(); }; if (ready) { setTimeout(readyFn); // таймаут для подписки на start } var sendData = function (_a, onData) { var _b, _c, _d; var action = _a.action, name = _a.name, requestId = _a.requestId; if ((_b = window.AssistantHost) === null || _b === void 0 ? void 0 : _b.sendDataContainer) { if (onData == null) { (_c = window.AssistantHost) === null || _c === void 0 ? void 0 : _c.sendDataContainer( /* eslint-disable-next-line @typescript-eslint/camelcase */ JSON.stringify({ data: action, message_name: name || '', requestId: requestId })); return function () { }; } if (requestId && observables.has(requestId)) { throw new Error('requestId должен быть уникальным'); } var realRequestId_1 = requestId || v4(); var subscribe = createNanoObservable(function (_a) { var _b; var next = _a.next; (_b = window.AssistantHost) === null || _b === void 0 ? void 0 : _b.sendDataContainer( /* eslint-disable-next-line @typescript-eslint/camelcase */ JSON.stringify({ data: action, message_name: name || '', requestId: realRequestId_1 })); observables.set(realRequestId_1, { next: next, requestId: requestId }); }).subscribe; var unsubscribe_1 = subscribe({ next: onData }).unsubscribe; return function () { unsubscribe_1(); observables.delete(realRequestId_1); }; } if (onData != null) { throw new Error('Не поддерживается в данной версии клиента'); } (_d = window.AssistantHost) === null || _d === void 0 ? void 0 : _d.sendData(JSON.stringify(action), name || null); return function () { }; }; return { cancelTts: cancelTts, close: function () { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.close(); }, getInitialData: appInitialData.pull, findInInitialData: appInitialData.find, getRecoveryState: function () { return window.appRecoveryState; }, on: on, sendAction: function (action, onData, onError, _a) { var _b = _a === void 0 ? {} : _a, name = _b.name, requestId = _b.requestId; return sendData({ action: action, name: name, requestId: requestId }, function (data) { if (data.type === 'smart_app_data' && onData) { onData(data.smart_app_data); return; } if (data.type === 'smart_app_error' && onError) { onError(data.smart_app_error); return; } emitCommand(data); }); }, sendData: sendData, setGetState: function (nextGetState) { currentGetState = nextGetState; }, setGetRecoveryState: function (nextGetRecoveryState) { currentGetRecoveryState = nextGetRecoveryState; }, setSuggests: function (suggestions) { var _a; (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.setSuggests(JSON.stringify({ suggestions: { buttons: suggestions } })); }, setHints: function (hints) { var _a; (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.setHints(JSON.stringify({ hints: hints })); }, sendText: function (message) { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.sendText(message); }, ready: readyFn, }; }; if (typeof window !== 'undefined') { // eslint-disable-next-line no-underscore-dangle window.__ASSISTANT_CLIENT__ = { version: '5.0.2' }; } export { createAssistant as c, v4 as v };