New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More

@sberdevices/assistant-client

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sberdevices/assistant-client - npm Package Compare versions

Comparing version 2.1.0-canary.58.03ac302471e41b44fd8a93a6dac19b85a3693042.0 to 2.1.0

@@ -0,1 +1,17 @@

# v2.1.0 (Mon Nov 30 2020)
#### 🚀 Enhancement
- feat: UMD для unpkg [#48](https://github.com/sberdevices/assistant-client/pull/48) ([@sasha-tlt](https://github.com/sasha-tlt))
#### 🐛 Bug Fix
- docs: Update README.md [#57](https://github.com/sberdevices/assistant-client/pull/57) ([@sasha-tlt](https://github.com/sasha-tlt))
#### Authors: 1
- Alexander Salmin ([@sasha-tlt](https://github.com/sasha-tlt))
---
# v2.0.1 (Tue Nov 24 2020)

@@ -2,0 +18,0 @@

@@ -0,1 +1,12 @@

var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {

@@ -14,12 +25,12 @@ var t = {};

import { createNanoEvents } from './nanoevents';
export const MESSAGE_NAMES = {
export var MESSAGE_NAMES = {
ANSWER_TO_USER: 'ANSWER_TO_USER',
STT: 'STT',
};
export const appendHeader = (buffer) => {
export var appendHeader = function (buffer) {
// Добавляем 4 байта в начало с длинной сообщения
const arrayBuffer = new ArrayBuffer(4);
const dataView = new DataView(arrayBuffer, 0);
var arrayBuffer = new ArrayBuffer(4);
var dataView = new DataView(arrayBuffer, 0);
dataView.setInt32(0, buffer.length, true);
const uint8Array = new Uint8Array(4 + buffer.length);
var uint8Array = new Uint8Array(4 + buffer.length);
uint8Array.set(new Uint8Array(arrayBuffer));

@@ -29,40 +40,41 @@ uint8Array.set(buffer, 4);

};
const compileBasePayload = ({ userId, token, userChannel, version, messageName, vpsToken, }) => {
var compileBasePayload = function (_a) {
var userId = _a.userId, token = _a.token, userChannel = _a.userChannel, version = _a.version, messageName = _a.messageName, vpsToken = _a.vpsToken;
if (version < 3) {
return {
userId,
token,
userChannel,
messageName,
vpsToken,
version,
userId: userId,
token: token,
userChannel: userChannel,
messageName: messageName,
vpsToken: vpsToken,
version: version,
};
}
return {
token,
messageName,
version,
token: token,
messageName: messageName,
version: version,
};
};
export const createClient = (clientParams, logger) => {
const { url, userId, token, userChannel, locale, device, settings, legacyDevice, version, messageName, vpsToken, } = clientParams;
const basePayload = compileBasePayload({ userId, token, messageName, vpsToken, userChannel, version });
let status = 'connecting';
const messageQueue = [];
const { on, emit, once } = createNanoEvents();
const pendingMessages = new Map();
const commitedMessages = new Map();
let currentSettings = { device, legacyDevice, settings, locale };
let currentMessageId = Date.now();
let retries = 0;
let destroyed = false;
let ws;
let timeOut;
let clearRetryTimer;
const getMessageId = () => {
export var createClient = function (clientParams, logger) {
var url = clientParams.url, userId = clientParams.userId, token = clientParams.token, userChannel = clientParams.userChannel, locale = clientParams.locale, device = clientParams.device, settings = clientParams.settings, legacyDevice = clientParams.legacyDevice, version = clientParams.version, messageName = clientParams.messageName, vpsToken = clientParams.vpsToken;
var basePayload = compileBasePayload({ userId: userId, token: token, messageName: messageName, vpsToken: vpsToken, userChannel: userChannel, version: version });
var status = 'connecting';
var messageQueue = [];
var _a = createNanoEvents(), on = _a.on, emit = _a.emit, once = _a.once;
var pendingMessages = new Map();
var commitedMessages = new Map();
var currentSettings = { device: device, legacyDevice: legacyDevice, settings: settings, locale: locale };
var currentMessageId = Date.now();
var retries = 0;
var destroyed = false;
var ws;
var timeOut;
var clearRetryTimer;
var getMessageId = function () {
return currentMessageId++;
};
const waitForAnswerToUser = (messageId) => {
return new Promise((resolve) => {
const off = on('systemMessage', (systemMessageData, originalMessage) => {
var waitForAnswerToUser = function (messageId) {
return new Promise(function (resolve) {
var off = on('systemMessage', function (systemMessageData, originalMessage) {
if (originalMessage.messageId === messageId &&

@@ -76,7 +88,7 @@ originalMessage.messageName === MESSAGE_NAMES.ANSWER_TO_USER) {

};
const send = (_a) => {
var { payload, messageId } = _a, other = __rest(_a, ["payload", "messageId"]);
const message = Message.create(Object.assign(Object.assign(Object.assign(Object.assign({ messageName: '' }, basePayload), payload), { messageId }), other));
const buffer = Message.encode(message).finish();
const bufferWithHeader = appendHeader(buffer);
var send = function (_a) {
var payload = _a.payload, messageId = _a.messageId, other = __rest(_a, ["payload", "messageId"]);
var message = Message.create(__assign(__assign(__assign(__assign({ messageName: '' }, basePayload), payload), { messageId: messageId }), other));
var buffer = Message.encode(message).finish();
var bufferWithHeader = appendHeader(buffer);
logger === null || logger === void 0 ? void 0 : logger.logOutcoming(message);

@@ -91,4 +103,6 @@ emit('outcoming', message);

};
const sendDevice = (data, last = true, messageId = getMessageId()) => {
currentSettings = Object.assign(Object.assign({}, currentSettings), { device: data });
var sendDevice = function (data, last, messageId) {
if (last === void 0) { last = true; }
if (messageId === void 0) { messageId = getMessageId(); }
currentSettings = __assign(__assign({}, currentSettings), { device: data });
return send({

@@ -99,8 +113,10 @@ payload: {

},
messageId,
messageId: messageId,
});
};
const sendInitialSettings = (data, last = true, messageId = getMessageId()) => {
var sendInitialSettings = function (data, last, messageId) {
if (last === void 0) { last = true; }
if (messageId === void 0) { messageId = getMessageId(); }
if (data.device && data.settings) {
currentSettings = Object.assign(Object.assign({}, currentSettings), { device: data.device, settings: data.settings, locale: data.locale || undefined });
currentSettings = __assign(__assign({}, currentSettings), { device: data.device, settings: data.settings, locale: data.locale || undefined });
}

@@ -112,7 +128,9 @@ return send({

},
messageId,
messageId: messageId,
});
};
const sendLegacyDevice = (data, last = true, messageId = getMessageId()) => {
currentSettings = Object.assign(Object.assign({}, currentSettings), { legacyDevice: data });
var sendLegacyDevice = function (data, last, messageId) {
if (last === void 0) { last = true; }
if (messageId === void 0) { messageId = getMessageId(); }
currentSettings = __assign(__assign({}, currentSettings), { legacyDevice: data });
return send({

@@ -123,7 +141,9 @@ payload: {

},
messageId,
messageId: messageId,
});
};
const sendSettings = (data, last = true, messageId = getMessageId()) => {
currentSettings = Object.assign(Object.assign({}, currentSettings), { settings: data });
var sendSettings = function (data, last, messageId) {
if (last === void 0) { last = true; }
if (messageId === void 0) { messageId = getMessageId(); }
currentSettings = __assign(__assign({}, currentSettings), { settings: data });
return send({

@@ -134,15 +154,21 @@ payload: {

},
messageId,
messageId: messageId,
});
};
const sendText = (data, params = {}, type = '', messageId = getMessageId()) => {
var sendText = function (data, params, type, messageId) {
var _a;
const text = type ? { data, type } : { data };
send(Object.assign({ payload: {
if (params === void 0) { params = {}; }
if (type === void 0) { type = ''; }
if (messageId === void 0) { messageId = getMessageId(); }
var text = type ? { data: data, type: type } : { data: data };
send(__assign({ payload: {
text: Text.create(text),
last: (_a = params.last) !== null && _a !== void 0 ? _a : 1,
}, messageId }, params));
}, messageId: messageId }, params));
return waitForAnswerToUser(messageId);
};
const sendSystemMessage = ({ data, messageName = '' }, last = true, messageId = getMessageId()) => {
var sendSystemMessage = function (_a, last, messageId) {
var data = _a.data, _b = _a.messageName, messageName = _b === void 0 ? '' : _b;
if (last === void 0) { last = true; }
if (messageId === void 0) { messageId = getMessageId(); }
send({

@@ -153,10 +179,12 @@ payload: {

}),
messageName,
messageName: messageName,
last: last ? 1 : -1,
},
messageId,
messageId: messageId,
});
return waitForAnswerToUser(messageId);
};
const sendVoice = (data, last = true, messageId = getMessageId()) => {
var sendVoice = function (data, last, messageId) {
if (last === void 0) { last = true; }
if (messageId === void 0) { messageId = getMessageId(); }
return send({

@@ -169,9 +197,9 @@ payload: {

},
messageId,
messageId: messageId,
});
};
const updateDefauls = (obj) => {
var updateDefauls = function (obj) {
Object.assign(basePayload, obj);
};
const destroy = () => {
var destroy = function () {
destroyed = true;

@@ -182,5 +210,5 @@ ws && ws.close();

};
const startWebSocket = () => {
var startWebSocket = function () {
status = 'connecting';
setTimeout(() => {
setTimeout(function () {
emit('connecting');

@@ -190,5 +218,5 @@ }, 0);

ws.binaryType = 'arraybuffer';
ws.addEventListener('open', () => {
ws.addEventListener('open', function () {
status = 'ready';
clearRetryTimer = window.setTimeout(() => {
clearRetryTimer = window.setTimeout(function () {
retries = 0;

@@ -208,4 +236,4 @@ }, 500);

sendInitialSettings({
userId,
userChannel,
userId: userId,
userChannel: userChannel,
device: currentSettings.device,

@@ -216,5 +244,5 @@ settings: currentSettings.settings,

}
logger === null || logger === void 0 ? void 0 : logger.logInit(Object.assign(Object.assign({}, clientParams), currentSettings));
logger === null || logger === void 0 ? void 0 : logger.logInit(__assign(__assign({}, clientParams), currentSettings));
while (messageQueue.length > 0) {
const message = messageQueue.shift();
var message = messageQueue.shift();
ws.send(message);

@@ -225,3 +253,3 @@ }

});
ws.addEventListener('close', () => {
ws.addEventListener('close', function () {
status = 'closed';

@@ -233,3 +261,3 @@ clearTimeout(clearRetryTimer);

}
timeOut = window.setTimeout(() => {
timeOut = window.setTimeout(function () {
startWebSocket();

@@ -241,6 +269,6 @@ retries++;

});
ws.addEventListener('message', (e) => {
ws.addEventListener('message', function (e) {
var _a;
const message = Message.decode(new Uint8Array(e.data).slice(4));
const messages = pendingMessages.get(message.messageId) || [];
var message = Message.decode(new Uint8Array(e.data).slice(4));
var messages = pendingMessages.get(message.messageId) || [];
logger === null || logger === void 0 ? void 0 : logger.logIncoming(message);

@@ -257,3 +285,3 @@ messages.push(message);

if ((_a = message.systemMessage) === null || _a === void 0 ? void 0 : _a.data) {
const systemMessage = JSON.parse(message.systemMessage.data);
var systemMessage = JSON.parse(message.systemMessage.data);
emit('systemMessage', systemMessage, message);

@@ -264,6 +292,6 @@ }

startWebSocket();
const batch = (cb) => {
const batchingMessageId = getMessageId();
let lastMessageSent = false;
const checkLastMessageStatus = (last) => {
var batch = function (cb) {
var batchingMessageId = getMessageId();
var lastMessageSent = false;
var checkLastMessageStatus = function (last) {
if (lastMessageSent) {

@@ -281,10 +309,14 @@ if (last) {

};
const threeParamsMethods = Object.entries({
sendDevice,
sendSettings,
sendInitialSettings,
sendLegacyDevice,
}).reduce((acc, curr) => {
const key = curr[0];
acc[key] = (...params) => {
var threeParamsMethods = Object.entries({
sendDevice: sendDevice,
sendSettings: sendSettings,
sendInitialSettings: sendInitialSettings,
sendLegacyDevice: sendLegacyDevice,
}).reduce(function (acc, curr) {
var key = curr[0];
acc[key] = function () {
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
checkLastMessageStatus(params[1]);

@@ -295,34 +327,39 @@ return curr[1](params[0], params[1], batchingMessageId);

}, {});
const upgradedSend = (params) => {
var upgradedSend = function (params) {
checkLastMessageStatus(params.payload.last === 1);
return send(Object.assign(Object.assign({}, params), { messageId: batchingMessageId }));
return send(__assign(__assign({}, params), { messageId: batchingMessageId }));
};
const upgradedSendText = (...[data, params, type]) => {
var upgradedSendText = function () {
var _a = [];
for (var _i = 0; _i < arguments.length; _i++) {
_a[_i] = arguments[_i];
}
var data = _a[0], params = _a[1], type = _a[2];
checkLastMessageStatus((params === null || params === void 0 ? void 0 : params.last) === 1);
return sendText(data, params, type, batchingMessageId);
};
const upgradedSendSystemMessage = (data, last) => {
var upgradedSendSystemMessage = function (data, last) {
checkLastMessageStatus(last);
return sendSystemMessage(data, last, batchingMessageId);
};
const upgradedSendVoice = (data, last) => {
var upgradedSendVoice = function (data, last) {
checkLastMessageStatus(last);
return sendVoice(data, last, batchingMessageId);
};
return cb(Object.assign(Object.assign({}, threeParamsMethods), { send: upgradedSend, sendText: upgradedSendText, sendSystemMessage: upgradedSendSystemMessage, sendVoice: upgradedSendVoice, messageId: batchingMessageId }));
return cb(__assign(__assign({}, threeParamsMethods), { send: upgradedSend, sendText: upgradedSendText, sendSystemMessage: upgradedSendSystemMessage, sendVoice: upgradedSendVoice, messageId: batchingMessageId }));
};
return {
once,
send,
sendDevice,
sendLegacyDevice,
sendSettings,
sendText,
sendVoice,
waitForAnswerToUser,
sendSystemMessage,
on,
updateDefauls,
destroy,
batch,
once: once,
send: send,
sendDevice: sendDevice,
sendLegacyDevice: sendLegacyDevice,
sendSettings: sendSettings,
sendText: sendText,
sendVoice: sendVoice,
waitForAnswerToUser: waitForAnswerToUser,
sendSystemMessage: sendSystemMessage,
on: on,
updateDefauls: updateDefauls,
destroy: destroy,
batch: batch,
get currentMessageId() {

@@ -329,0 +366,0 @@ return currentMessageId;

@@ -1,19 +0,19 @@

const AudioContext = window.AudioContext || window.webkitAudioContext;
let context;
let processor;
const downsampleBuffer = (buffer, sampleRate, outSampleRate) => {
var AudioContext = window.AudioContext || window.webkitAudioContext;
var context;
var processor;
var downsampleBuffer = function (buffer, sampleRate, outSampleRate) {
if (outSampleRate > sampleRate) {
throw new Error('downsampling rate show be smaller than original sample rate');
}
const sampleRateRatio = sampleRate / outSampleRate;
const newLength = Math.round(buffer.length / sampleRateRatio);
const result = new Int16Array(newLength);
let empty = true;
let offsetResult = 0;
let offsetBuffer = 0;
var sampleRateRatio = sampleRate / outSampleRate;
var newLength = Math.round(buffer.length / sampleRateRatio);
var result = new Int16Array(newLength);
var empty = true;
var offsetResult = 0;
var offsetBuffer = 0;
while (offsetResult < result.length) {
const nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
let accum = 0;
let count = 0;
for (let i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
var accum = 0;
var count = 0;
for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
accum += buffer[i];

@@ -31,10 +31,10 @@ count++;

buffer: result.buffer,
empty,
empty: empty,
};
};
const TARGET_SAMPLE_RATE = 16000;
const createAudioRecorder = (stream, cb) => {
let state = 'inactive';
let input;
const start = () => {
var TARGET_SAMPLE_RATE = 16000;
var createAudioRecorder = function (stream, cb) {
var state = 'inactive';
var input;
var start = function () {
if (state !== 'inactive') {

@@ -53,6 +53,6 @@ throw new Error("Can't start not inactive recorder");

}
const listener = (e) => {
const buffer = e.inputBuffer.getChannelData(0);
const data = downsampleBuffer(buffer, context.sampleRate, TARGET_SAMPLE_RATE);
const last = state === 'inactive';
var listener = function (e) {
var buffer = e.inputBuffer.getChannelData(0);
var data = downsampleBuffer(buffer, context.sampleRate, TARGET_SAMPLE_RATE);
var last = state === 'inactive';
cb(data.buffer, last);

@@ -67,3 +67,3 @@ if (last) {

};
const stop = () => {
var stop = function () {
if (state === 'inactive') {

@@ -73,3 +73,3 @@ throw new Error("Can't stop inactive recorder");

state = 'inactive';
stream.getTracks().forEach((track) => {
stream.getTracks().forEach(function (track) {
track.stop();

@@ -82,6 +82,8 @@ });

};
export const createNavigatorAudioProvider = (cb) => navigator.mediaDevices
.getUserMedia({
audio: true,
})
.then((stream) => createAudioRecorder(stream, cb));
export var createNavigatorAudioProvider = function (cb) {
return navigator.mediaDevices
.getUserMedia({
audio: true,
})
.then(function (stream) { return createAudioRecorder(stream, cb); });
};

@@ -5,8 +5,9 @@ import { PacketWrapperFromServer } from './asr';

import { createNanoEvents } from './nanoevents';
export const createVoiceListener = (createAudioProvider = createNavigatorAudioProvider) => {
const { emit, on } = createNanoEvents();
let stopRecord;
let off;
let status = 'stopped';
const stop = () => {
export var createVoiceListener = function (createAudioProvider) {
if (createAudioProvider === void 0) { createAudioProvider = createNavigatorAudioProvider; }
var _a = createNanoEvents(), emit = _a.emit, on = _a.on;
var stopRecord;
var off;
var status = 'stopped';
var stop = function () {
status = 'stopped';

@@ -17,7 +18,8 @@ off();

};
const listen = ({ sendVoice, messageId, onMessage, }) => {
var listen = function (_a) {
var sendVoice = _a.sendVoice, messageId = _a.messageId, onMessage = _a.onMessage;
status = 'listen';
createAudioProvider((data, last) => sendVoice(new Uint8Array(data), last)).then((recStop) => {
createAudioProvider(function (data, last) { return sendVoice(new Uint8Array(data), last); }).then(function (recStop) {
stopRecord = recStop;
off = onMessage((message) => {
off = onMessage(function (message) {
var _a, _b;

@@ -35,3 +37,3 @@ if (message.status && message.status.code != null && message.status.code < 0) {

if ((_a = message.bytes) === null || _a === void 0 ? void 0 : _a.data) {
const { decoderResultField } = PacketWrapperFromServer.decode(message.bytes.data);
var decoderResultField = PacketWrapperFromServer.decode(message.bytes.data).decoderResultField;
if (decoderResultField && ((_b = decoderResultField.hypothesis) === null || _b === void 0 ? void 0 : _b.length)) {

@@ -50,5 +52,5 @@ emit('hypotesis', decoderResultField.hypothesis[0].normalizedText || '', !!decoderResultField.isFinal);

return {
listen,
stop,
on,
listen: listen,
stop: stop,
on: on,
get status() {

@@ -55,0 +57,0 @@ return status;

import { createNanoEvents } from './nanoevents';
const AudioContext = window.AudioContext || window.webkitAudioContext;
const from16BitToFloat32 = (incomingData) => {
const l = incomingData.length;
const outputData = new Float32Array(l);
for (let i = 0; i < l; i += 1) {
var AudioContext = window.AudioContext || window.webkitAudioContext;
var from16BitToFloat32 = function (incomingData) {
var l = incomingData.length;
var outputData = new Float32Array(l);
for (var i = 0; i < l; i += 1) {
outputData[i] = incomingData[i] / 32768.0;

@@ -11,9 +11,9 @@ }

};
const createChunkQueue = () => {
const buffer = []; // очередь на воспроизведение
const chunks = []; // очередь воспроизведения
let duration = 0; // продолжительность очереди на воспроизведение
let loaded = false; // флаг завершения загрузки
var createChunkQueue = function () {
var buffer = []; // очередь на воспроизведение
var chunks = []; // очередь воспроизведения
var duration = 0; // продолжительность очереди на воспроизведение
var loaded = false; // флаг завершения загрузки
/** Добавить чанк в очередь на воспроизведение */
const push = (chunk) => {
var push = function (chunk) {
var _a;

@@ -24,11 +24,11 @@ buffer.push(chunk);

/** Добавить чанк в очередь воспроизведения */
const toPlay = (chunk) => {
var toPlay = function (chunk) {
chunks.push(chunk);
};
/** Удалить чанк из очереди воспроизведения */
const remove = (chunk) => {
var remove = function (chunk) {
chunks.splice(chunks.indexOf(chunk), 1);
};
/** Получить очередь на воспроизведение */
const popAll = () => {
var popAll = function () {
duration = 0;

@@ -38,3 +38,3 @@ return buffer.splice(0, buffer.length);

/** Проставляем признак окончания загрузки трека */
const allLoaded = () => {
var allLoaded = function () {
loaded = true;

@@ -46,7 +46,7 @@ };

},
allLoaded,
toPlay,
remove,
push,
popAll,
allLoaded: allLoaded,
toPlay: toPlay,
remove: remove,
push: push,
popAll: popAll,
get length() {

@@ -67,10 +67,11 @@ return chunks.length;

};
const createTrackStream = (ctx, { sampleRate = 24000, numberOfChannels = 1, delay = 0, onPlay, onEnd, trackStatus, }) => {
const queue = createChunkQueue();
let extraByte = null;
let status = trackStatus || 'stop';
let lastChunkOffset = 0;
let startTime = 0;
let firstChunk = true;
const end = () => {
var createTrackStream = function (ctx, _a) {
var _b = _a.sampleRate, sampleRate = _b === void 0 ? 24000 : _b, _c = _a.numberOfChannels, numberOfChannels = _c === void 0 ? 1 : _c, _d = _a.delay, delay = _d === void 0 ? 0 : _d, onPlay = _a.onPlay, onEnd = _a.onEnd, trackStatus = _a.trackStatus;
var queue = createChunkQueue();
var extraByte = null;
var status = trackStatus || 'stop';
var lastChunkOffset = 0;
var startTime = 0;
var firstChunk = true;
var end = function () {
status = 'end';

@@ -81,3 +82,3 @@ onEnd && onEnd();

};
const play = () => {
var play = function () {
if (status === 'end') {

@@ -96,4 +97,4 @@ return;

startTime = queue.length === 0 ? ctx.currentTime : startTime;
const chunks = queue.popAll();
chunks.forEach((chunk) => {
var chunks = queue.popAll();
chunks.forEach(function (chunk) {
var _a;

@@ -106,3 +107,3 @@ queue.toPlay(chunk);

};
const getExtraBytes = (data, bytesArraysSizes) => {
var getExtraBytes = function (data, bytesArraysSizes) {
if (extraByte == null && bytesArraysSizes.incomingMessageVoiceDataLength % 2) {

@@ -126,8 +127,8 @@ extraByte = data[bytesArraysSizes.incomingMessageVoiceDataLength - 1];

};
const createChunk = (chunk) => {
const audioBuffer = ctx.createBuffer(numberOfChannels, chunk.length / numberOfChannels, sampleRate);
for (let i = 0; i < numberOfChannels; i++) {
const channelChunk = new Float32Array(chunk.length / numberOfChannels);
let index = 0;
for (let j = i; j < chunk.length; j += numberOfChannels) {
var createChunk = function (chunk) {
var audioBuffer = ctx.createBuffer(numberOfChannels, chunk.length / numberOfChannels, sampleRate);
for (var i = 0; i < numberOfChannels; i++) {
var channelChunk = new Float32Array(chunk.length / numberOfChannels);
var index = 0;
for (var j = i; j < chunk.length; j += numberOfChannels) {
channelChunk[index++] = chunk[j];

@@ -137,6 +138,6 @@ }

}
const source = ctx.createBufferSource();
var source = ctx.createBufferSource();
source.buffer = audioBuffer;
source.connect(ctx.destination);
source.onended = () => {
source.onended = function () {
queue.remove(source);

@@ -150,6 +151,6 @@ if (queue.ended) {

};
const write = (data) => {
var write = function (data) {
// 44 байта - заголовок трека
const slicePoint = firstChunk ? 44 : 0;
const bytesArraysSizes = {
var slicePoint = firstChunk ? 44 : 0;
var bytesArraysSizes = {
incomingMessageVoiceDataLength: data.length,

@@ -162,5 +163,5 @@ sourceLen: data.length,

getExtraBytes(data, bytesArraysSizes);
const dataBuffer = new ArrayBuffer(bytesArraysSizes.incomingMessageVoiceDataLength);
const bufferUi8 = new Uint8Array(dataBuffer);
const bufferI16 = new Int16Array(dataBuffer);
var dataBuffer = new ArrayBuffer(bytesArraysSizes.incomingMessageVoiceDataLength);
var bufferUi8 = new Uint8Array(dataBuffer);
var bufferI16 = new Int16Array(dataBuffer);
bufferUi8.set(data.slice(0, bytesArraysSizes.sourceLen), bytesArraysSizes.start);

@@ -170,3 +171,3 @@ if (bytesArraysSizes.prepend != null) {

}
const chunk = createChunk(from16BitToFloat32(bufferI16.slice(slicePoint)));
var chunk = createChunk(from16BitToFloat32(bufferI16.slice(slicePoint)));
queue.push(chunk);

@@ -181,3 +182,3 @@ if (status === 'play') {

},
setLoaded: () => {
setLoaded: function () {
queue.allLoaded();

@@ -188,18 +189,18 @@ if (status === 'play') {

},
write,
write: write,
get status() {
return status;
},
play,
play: play,
stop: end,
};
};
const createTrackCollection = () => {
let trackIds;
let trackMap;
const clear = () => {
var createTrackCollection = function () {
var trackIds;
var trackMap;
var clear = function () {
trackIds = new Array();
trackMap = new Map();
};
const add = (id, track) => {
var add = function (id, track) {
if (trackMap.has(id)) {

@@ -211,5 +212,5 @@ throw new Error('Track already exists');

};
const has = (id) => trackMap.has(id);
const getById = (id) => {
const track = trackMap.get(id);
var has = function (id) { return trackMap.has(id); };
var getById = function (id) {
var track = trackMap.get(id);
if (track === undefined) {

@@ -220,7 +221,7 @@ throw new Error('Unknown track id');

};
const getByIndex = (index) => {
var getByIndex = function (index) {
if (index < 0 || index >= trackIds.length) {
throw new Error('Index out of bounds');
}
const track = trackMap.get(trackIds[index]);
var track = trackMap.get(trackIds[index]);
if (track == null) {

@@ -231,11 +232,11 @@ throw new Error('Something wrong...');

};
const some = (predicate) => trackIds.some((id) => predicate(getById(id)));
var some = function (predicate) { return trackIds.some(function (id) { return predicate(getById(id)); }); };
clear();
return {
clear,
has,
clear: clear,
has: has,
get: getById,
getByIndex,
add,
some,
getByIndex: getByIndex,
add: add,
some: some,
get length() {

@@ -246,12 +247,13 @@ return trackIds.length;

};
export const createVoicePlayer = ({ startVoiceDelay = 0.2, sampleRate, numberOfChannels, } = {}) => {
const { on, emit } = createNanoEvents();
const tracks = createTrackCollection();
export var createVoicePlayer = function (_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.startVoiceDelay, startVoiceDelay = _c === void 0 ? 0.2 : _c, sampleRate = _b.sampleRate, numberOfChannels = _b.numberOfChannels;
var _d = createNanoEvents(), on = _d.on, emit = _d.emit;
var tracks = createTrackCollection();
// true - воспроизводим все треки в очереди (новые в том числе), false - скипаем всю очередь (новые в т.ч.)
let active = true;
let ctx = null;
let cursor = 0;
const play = () => {
var active = true;
var ctx = null;
var cursor = 0;
var play = function () {
if (cursor >= tracks.length) {
if (tracks.some((track) => !track.loaded)) {
if (tracks.some(function (track) { return !track.loaded; })) {
return;

@@ -265,3 +267,3 @@ }

}
const current = tracks.getByIndex(cursor);
var current = tracks.getByIndex(cursor);
if (current.status === 'end') {

@@ -277,4 +279,5 @@ if (cursor < tracks.length) {

};
const append = (data, trackId, last = false) => {
let current = tracks.has(trackId) ? tracks.get(trackId) : undefined;
var append = function (data, trackId, last) {
if (last === void 0) { last = false; }
var current = tracks.has(trackId) ? tracks.get(trackId) : undefined;
if (current == null) {

@@ -286,7 +289,7 @@ if (ctx == null) {

current = createTrackStream(ctx, {
sampleRate,
numberOfChannels,
sampleRate: sampleRate,
numberOfChannels: numberOfChannels,
delay: startVoiceDelay,
onPlay: () => emit('play', trackId),
onEnd: () => {
onPlay: function () { return emit('play', trackId); },
onEnd: function () {
emit('end', trackId);

@@ -307,3 +310,3 @@ play();

};
const stop = () => {
var stop = function () {
while (cursor < tracks.length) {

@@ -315,3 +318,3 @@ tracks.getByIndex(cursor).stop();

return {
append,
append: append,
get active() {

@@ -329,4 +332,4 @@ return active;

},
on,
on: on,
};
};
/* eslint-disable @typescript-eslint/camelcase */
/* eslint-disable no-underscore-dangle */
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import axios from 'axios';
import { v4 } from 'uuid';
const STATE_UPDATE_TIMEOUT = 200;
const createMessage = (props) => {
const messageName = props.data ? 'SERVER_ACTION' : props.name || 'MESSAGE_TO_SKILL';
const systemMessage = props.data
var STATE_UPDATE_TIMEOUT = 200;
var createMessage = function (props) {
var messageName = props.data ? 'SERVER_ACTION' : props.name || 'MESSAGE_TO_SKILL';
var systemMessage = props.data
? {

@@ -18,3 +29,3 @@ systemMessage: {

: {};
const payload = {
var payload = {
payload: {

@@ -36,3 +47,3 @@ applicationId: props.applicationId,

};
return Object.assign(Object.assign({ messageName, sessionId: props.sessionId, messageId: String(Math.floor(Math.random() * Math.floor(9999999))), meta: {
return __assign(__assign({ messageName: messageName, sessionId: props.sessionId, messageId: String(Math.floor(Math.random() * Math.floor(9999999))), meta: {
current_app: {

@@ -46,22 +57,25 @@ state: props.state,

};
const defaultConfig = {
var defaultConfig = {
request: {
url: 'sberbank.ru',
},
onRequest: (props) => props,
onResponse: (res) => res,
onError: () => { },
onRequest: function (props) { return props; },
onResponse: function (res) { return res; },
onError: function () { },
};
export function initializeDebugging(config = defaultConfig) {
const currentAppState = {};
const sessionId = v4();
const userId = v4();
const applicationId = v4();
const appVersionId = v4();
const createMessageInSession = (props) => createMessage(Object.assign({ config,
userId,
sessionId,
applicationId,
appVersionId, state: currentAppState }, props));
const ask = (props) => {
export function initializeDebugging(config) {
if (config === void 0) { config = defaultConfig; }
var currentAppState = {};
var sessionId = v4();
var userId = v4();
var applicationId = v4();
var appVersionId = v4();
var createMessageInSession = function (props) {
return createMessage(__assign({ config: config,
userId: userId,
sessionId: sessionId,
applicationId: applicationId,
appVersionId: appVersionId, state: currentAppState }, props));
};
var ask = function (props) {
var _a, _b;

@@ -75,3 +89,3 @@ return axios({

.then(config.onResponse)
.then((action) => {
.then(function (action) {
var _a;

@@ -85,5 +99,5 @@ if (action && ((_a = window.AssistantClient) === null || _a === void 0 ? void 0 : _a.onData)) {

window.AssistantHost = {
close() { },
ready() {
setTimeout(() => {
close: function () { },
ready: function () {
setTimeout(function () {
var _a;

@@ -94,28 +108,34 @@ if ((_a = window.AssistantClient) === null || _a === void 0 ? void 0 : _a.onStart)

},
sendData(data, name) {
sendData: function (data, name) {
ask({
data,
data: data,
name: name || undefined,
});
},
sendDataContainer(container) {
const { data, message_name } = JSON.parse(container);
sendDataContainer: function (container) {
var _a = JSON.parse(container), data = _a.data, message_name = _a.message_name;
ask({
data,
data: data,
name: message_name || undefined,
});
},
setSuggest() { },
setSuggest: function () { },
};
window.__dangerouslyGetAssistantAppState = () => (Object.assign({}, currentAppState));
window.__dangerouslySendVoiceMessage = (text) => {
window.__dangerouslyGetAssistantAppState = function () { return (__assign({}, currentAppState)); };
window.__dangerouslySendVoiceMessage = function (text) {
var _a;
if ((_a = window.AssistantClient) === null || _a === void 0 ? void 0 : _a.onRequestState)
window.AssistantClient.onRequestState();
setTimeout(() => ask({
text,
}), STATE_UPDATE_TIMEOUT);
setTimeout(function () {
return ask({
text: text,
});
}, STATE_UPDATE_TIMEOUT);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window.__dangerouslySendDataMessage = (data, name = null) => { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.sendData(JSON.stringify(data), name); };
window.__dangerouslySendDataMessage = function (data, name) {
var _a;
if (name === void 0) { name = null; }
return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.sendData(JSON.stringify(data), name);
};
}
import { NativePanelParams } from './NativePanel/NativePanel';
import { SystemMessageDataType, ClientLogger, VoicePlayerSettings, AssistantSettings } from './typings';
export declare const legacyDevice: {
clientType: string;
channel: string;
channelVersion: string;
platformName: string;
platformVersion: string;
};
export declare const initializeAssistantSDK: ({ initPhrase, url, userChannel, surface, userId, token, surfaceVersion, deviceId, locale, nativePanel, sdkVersion, enableRecord, recordParams, settings, voiceSettings, vpsVersion, }: {

@@ -11,0 +4,0 @@ initPhrase: string;

/* eslint-disable no-unused-expressions, @typescript-eslint/camelcase, no-underscore-dangle */
/* eslint-disable @typescript-eslint/ban-ts-ignore */
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

@@ -12,2 +23,29 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }

};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __rest = (this && this.__rest) || function (s, e) {

@@ -33,12 +71,12 @@ var t = {};

import { createVoicePlayer } from './createVoicePlayer';
const SDK_VERSION = '20.09.1.3576';
const APP_VERSION = '20.09.1.3576';
const CAPABILITIES = JSON.stringify({
var SDK_VERSION = '20.09.1.3576';
var APP_VERSION = '20.09.1.3576';
var CAPABILITIES = JSON.stringify({
screen: { available: true, width: window.innerWidth, height: window.innerHeight },
speak: { available: true },
});
const FEATURES = JSON.stringify({
var FEATURES = JSON.stringify({
appTypes: ['DIALOG', 'WEB_APP'],
});
export const legacyDevice = {
var legacyDevice = {
clientType: 'simple',

@@ -50,15 +88,16 @@ channel: 'Android_SB',

};
export const initializeAssistantSDK = ({ initPhrase, url, userChannel, surface, userId = `webdbg_userid_${Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)}`, token = `webdbg_eribtoken_${Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)}`, surfaceVersion, deviceId, locale = 'ru', nativePanel = {
defaultText: 'Покажи что-нибудь',
render: renderNativePanel,
}, sdkVersion = SDK_VERSION, enableRecord, recordParams, settings = {}, voiceSettings, vpsVersion = 3, }) => {
const device = {
export var initializeAssistantSDK = function (_a) {
var initPhrase = _a.initPhrase, url = _a.url, userChannel = _a.userChannel, surface = _a.surface, _b = _a.userId, userId = _b === void 0 ? "webdbg_userid_" + (Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)) : _b, _c = _a.token, token = _c === void 0 ? "webdbg_eribtoken_" + (Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)) : _c, surfaceVersion = _a.surfaceVersion, deviceId = _a.deviceId, _d = _a.locale, locale = _d === void 0 ? 'ru' : _d, _e = _a.nativePanel, nativePanel = _e === void 0 ? {
defaultText: 'Покажи что-нибудь',
render: renderNativePanel,
} : _e, _f = _a.sdkVersion, sdkVersion = _f === void 0 ? SDK_VERSION : _f, enableRecord = _a.enableRecord, recordParams = _a.recordParams, _g = _a.settings, settings = _g === void 0 ? {} : _g, voiceSettings = _a.voiceSettings, _h = _a.vpsVersion, vpsVersion = _h === void 0 ? 3 : _h;
var device = {
platformType: 'WEBDBG',
platformVersion: '1.0',
sdkVersion,
surface,
sdkVersion: sdkVersion,
surface: surface,
surfaceVersion: surfaceVersion || APP_VERSION,
features: FEATURES,
capabilities: CAPABILITIES,
deviceId,
deviceId: deviceId,
additionalInfo: JSON.stringify({

@@ -69,32 +108,32 @@ host_app_id: 'ru.sberbank.sdakit.demo',

};
const voicePlayer = createVoicePlayer(voiceSettings);
let clientLogger = (recordParams === null || recordParams === void 0 ? void 0 : recordParams.logger) ? recordParams.logger : createConsoleLogger();
let loggerCb;
const recorder = createLogCallbackRecorder((subscribe) => {
var voicePlayer = createVoicePlayer(voiceSettings);
var clientLogger = (recordParams === null || recordParams === void 0 ? void 0 : recordParams.logger) ? recordParams.logger : createConsoleLogger();
var loggerCb;
var recorder = createLogCallbackRecorder(function (subscribe) {
loggerCb = subscribe;
}, (recordParams === null || recordParams === void 0 ? void 0 : recordParams.defaultActive) != null ? recordParams.defaultActive : true);
const saver = createRecordDownloader();
var saver = createRecordDownloader();
if (enableRecord && (recordParams === null || recordParams === void 0 ? void 0 : recordParams.logger) == null) {
clientLogger = createCallbackLogger((logEntry) => loggerCb && loggerCb(logEntry));
clientLogger = createCallbackLogger(function (logEntry) { return loggerCb && loggerCb(logEntry); });
}
const vpsClient = createClient({
url,
userId,
token,
userChannel,
locale,
device,
legacyDevice,
settings: Object.assign(Object.assign({}, settings), { dubbing: settings.dubbing === false ? -1 : 1, echo: settings.echo || -1 }),
var vpsClient = createClient({
url: url,
userId: userId,
token: token,
userChannel: userChannel,
locale: locale,
device: device,
legacyDevice: legacyDevice,
settings: __assign(__assign({}, settings), { dubbing: settings.dubbing === false ? -1 : 1, echo: settings.echo || -1 }),
version: vpsVersion,
}, clientLogger);
let appInfo;
const initialSmartAppData = [];
const requestIdMap = {};
let clientReady = false; // флаг готовности клиента к приему onData
let assistantReady = false; // флаг готовности контекста ассистента
var appInfo;
var initialSmartAppData = [];
var requestIdMap = {};
var clientReady = false; // флаг готовности клиента к приему onData
var assistantReady = false; // флаг готовности контекста ассистента
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let state = null;
let character;
const createSystemMessageBase = () => {
var state = null;
var character;
var createSystemMessageBase = function () {
return {

@@ -105,3 +144,3 @@ app_info: appInfo,

app_info: appInfo,
state,
state: state,
},

@@ -111,4 +150,5 @@ },

};
const sendServerAction = ({ data, message_name, requestId, }) => {
let messageId;
var sendServerAction = function (_a) {
var data = _a.data, message_name = _a.message_name, requestId = _a.requestId;
var messageId;
if (requestId) {

@@ -119,7 +159,7 @@ messageId = Date.now();

return vpsClient.sendSystemMessage({
data: Object.assign(Object.assign({}, createSystemMessageBase()), { server_action: data }),
data: __assign(__assign({}, createSystemMessageBase()), { server_action: data }),
messageName: message_name || 'SERVER_ACTION',
}, undefined, messageId);
};
const updateState = () => {
var updateState = function () {
var _a;

@@ -130,10 +170,12 @@ if ((_a = window.AssistantClient) === null || _a === void 0 ? void 0 : _a.onRequestState) {

};
const sendText = (text, params = {}) => {
var sendText = function (text, params) {
if (params === void 0) { params = {}; }
voicePlayer.active = false;
voicePlayer.active = true;
updateState();
return vpsClient.batch(({ sendText: batchedSendText, sendSystemMessage }) => {
return vpsClient.batch(function (_a) {
var batchedSendText = _a.sendText, sendSystemMessage = _a.sendSystemMessage;
state &&
sendSystemMessage({
data: Object.assign({}, createSystemMessageBase()),
data: __assign({}, createSystemMessageBase()),
messageName: '',

@@ -144,34 +186,48 @@ }, false);

};
const fn = () => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b, _c;
yield new Promise((resolve) => {
vpsClient.on('ready', resolve);
var fn = function () { return __awaiter(void 0, void 0, void 0, function () {
var messageId, res, _i, _a, item, _b, initialSmartAppData_1, smartAppData;
var _c, _d, _e;
return __generator(this, function (_f) {
switch (_f.label) {
case 0: return [4 /*yield*/, new Promise(function (resolve) {
vpsClient.on('ready', resolve);
})];
case 1:
_f.sent();
return [4 /*yield*/, vpsClient.sendSystemMessage({ data: {}, messageName: 'OPEN_ASSISTANT' })];
case 2:
_f.sent();
if (!initPhrase) return [3 /*break*/, 4];
messageId = vpsClient.currentMessageId;
return [4 /*yield*/, vpsClient.sendText(initPhrase)];
case 3:
res = _f.sent();
appInfo = res === null || res === void 0 ? void 0 : res.app_info;
if (res === null || res === void 0 ? void 0 : res.character) {
character = res === null || res === void 0 ? void 0 : res.character.id;
initialSmartAppData.push({ type: 'character', character: res.character });
}
for (_i = 0, _a = (res === null || res === void 0 ? void 0 : res.items) || []; _i < _a.length; _i++) {
item = _a[_i];
if (item.command != null) {
initialSmartAppData.push(__assign(__assign({}, item.command), { sdkMeta: { mid: messageId } }));
}
}
if (clientReady && ((_c = window.AssistantClient) === null || _c === void 0 ? void 0 : _c.onData)) {
((_d = window.AssistantClient) === null || _d === void 0 ? void 0 : _d.onStart) && ((_e = window.AssistantClient) === null || _e === void 0 ? void 0 : _e.onStart());
for (_b = 0, initialSmartAppData_1 = initialSmartAppData; _b < initialSmartAppData_1.length; _b++) {
smartAppData = initialSmartAppData_1[_b];
window.AssistantClient.onData(smartAppData);
}
}
assistantReady = true;
_f.label = 4;
case 4: return [2 /*return*/];
}
});
yield vpsClient.sendSystemMessage({ data: {}, messageName: 'OPEN_ASSISTANT' });
if (initPhrase) {
const messageId = vpsClient.currentMessageId;
const res = yield vpsClient.sendText(initPhrase);
appInfo = res === null || res === void 0 ? void 0 : res.app_info;
if (res === null || res === void 0 ? void 0 : res.character) {
character = res === null || res === void 0 ? void 0 : res.character.id;
initialSmartAppData.push({ type: 'character', character: res.character });
}
for (const item of (res === null || res === void 0 ? void 0 : res.items) || []) {
if (item.command != null) {
initialSmartAppData.push(Object.assign(Object.assign({}, item.command), { sdkMeta: { mid: messageId } }));
}
}
if (clientReady && ((_a = window.AssistantClient) === null || _a === void 0 ? void 0 : _a.onData)) {
((_b = window.AssistantClient) === null || _b === void 0 ? void 0 : _b.onStart) && ((_c = window.AssistantClient) === null || _c === void 0 ? void 0 : _c.onStart());
for (const smartAppData of initialSmartAppData) {
window.AssistantClient.onData(smartAppData);
}
}
assistantReady = true;
}
});
const promise = fn();
}); };
var promise = fn();
window.appInitialData = initialSmartAppData;
window.AssistantHost = {
close() {
close: function () {
appInfo = undefined;

@@ -182,7 +238,8 @@ initialSmartAppData.splice(0, initialSmartAppData.length);

},
ready() {
ready: function () {
var _a, _b, _c;
if (assistantReady && ((_a = window.AssistantClient) === null || _a === void 0 ? void 0 : _a.onData)) {
((_b = window.AssistantClient) === null || _b === void 0 ? void 0 : _b.onStart) && ((_c = window.AssistantClient) === null || _c === void 0 ? void 0 : _c.onStart());
for (const smartAppData of initialSmartAppData) {
for (var _i = 0, initialSmartAppData_2 = initialSmartAppData; _i < initialSmartAppData_2.length; _i++) {
var smartAppData = initialSmartAppData_2[_i];
window.AssistantClient.onData(smartAppData);

@@ -193,22 +250,41 @@ }

},
sendData(payload, messageName = null) {
return __awaiter(this, void 0, void 0, function* () {
yield promise;
updateState();
sendServerAction({ data: JSON.parse(payload), message_name: messageName || undefined });
sendData: function (payload, messageName) {
if (messageName === void 0) { messageName = null; }
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, promise];
case 1:
_a.sent();
updateState();
sendServerAction({ data: JSON.parse(payload), message_name: messageName || undefined });
return [2 /*return*/];
}
});
});
},
sendDataContainer(container) {
return __awaiter(this, void 0, void 0, function* () {
yield promise;
updateState();
sendServerAction(JSON.parse(container));
sendDataContainer: function (container) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, promise];
case 1:
_a.sent();
updateState();
sendServerAction(JSON.parse(container));
return [2 /*return*/];
}
});
});
},
setSuggest() { },
setSuggest: function () { },
};
const voiceListener = createVoiceListener();
const subscribeToListenerStatus = (cb) => voiceListener.on('status', cb);
const subscribeToListenerHypotesis = (cb) => voiceListener.on('hypotesis', cb);
voiceListener.on('status', (status) => {
var voiceListener = createVoiceListener();
var subscribeToListenerStatus = function (cb) {
return voiceListener.on('status', cb);
};
var subscribeToListenerHypotesis = function (cb) {
return voiceListener.on('hypotesis', cb);
};
voiceListener.on('status', function (status) {
if (status === 'listen') {

@@ -221,3 +297,3 @@ voicePlayer.active = false;

});
const handleListen = () => {
var handleListen = function () {
if (voiceListener.status === 'listen') {

@@ -228,22 +304,25 @@ voiceListener.stop();

updateState();
vpsClient.batch(({ sendSystemMessage, sendVoice, messageId }) => {
vpsClient.batch(function (_a) {
var sendSystemMessage = _a.sendSystemMessage, sendVoice = _a.sendVoice, messageId = _a.messageId;
state &&
sendSystemMessage({
data: Object.assign({}, createSystemMessageBase()),
data: __assign({}, createSystemMessageBase()),
messageName: '',
}, false);
voiceListener.listen({
sendVoice,
messageId,
onMessage: (cb) => vpsClient.on('message', cb),
sendVoice: sendVoice,
messageId: messageId,
onMessage: function (cb) { return vpsClient.on('message', cb); },
});
});
};
const updateDevUI = (suggestions = [], bubbleText = '') => {
var updateDevUI = function (suggestions, bubbleText) {
if (suggestions === void 0) { suggestions = []; }
if (bubbleText === void 0) { bubbleText = ''; }
if (nativePanel) {
const { render } = nativePanel, props = __rest(nativePanel, ["render"]);
(render || renderNativePanel)(Object.assign(Object.assign({}, props), { sendText, onListen: handleListen, suggestions: suggestions || [], bubbleText, onSubscribeListenStatus: subscribeToListenerStatus, onSubscribeHypotesis: subscribeToListenerHypotesis }));
var render = nativePanel.render, props = __rest(nativePanel, ["render"]);
(render || renderNativePanel)(__assign(__assign({}, props), { sendText: sendText, onListen: handleListen, suggestions: suggestions || [], bubbleText: bubbleText, onSubscribeListenStatus: subscribeToListenerStatus, onSubscribeHypotesis: subscribeToListenerHypotesis }));
}
};
const emitOnData = (command) => {
var emitOnData = function (command) {
var _a;

@@ -254,6 +333,7 @@ if (clientReady && assistantReady && ((_a = window.AssistantClient) === null || _a === void 0 ? void 0 : _a.onData)) {

};
vpsClient.on('systemMessage', (message, original) => {
vpsClient.on('systemMessage', function (message, original) {
var _a, _b;
let bubbleText = '';
for (const item of message.items) {
var bubbleText = '';
for (var _i = 0, _c = message.items; _i < _c.length; _i++) {
var item = _c[_i];
if (item.bubble) {

@@ -263,3 +343,3 @@ bubbleText = item.bubble.text;

if (item.command) {
emitOnData(Object.assign(Object.assign({}, item.command), { sdkMeta: { mid: original.messageId, requestId: requestIdMap[original.messageId.toString()] } }));
emitOnData(__assign(__assign({}, item.command), { sdkMeta: { mid: original.messageId, requestId: requestIdMap[original.messageId.toString()] } }));
}

@@ -273,3 +353,3 @@ }

});
vpsClient.on('message', (message) => {
vpsClient.on('message', function (message) {
if (message.voice) {

@@ -282,3 +362,3 @@ voicePlayer.append(message.voice.data || new Uint8Array(), message.messageId.toString(), message.last === 1);

return {
sendText,
sendText: sendText,
on: vpsClient.on,

@@ -285,0 +365,0 @@ destroy: vpsClient.destroy,

@@ -1,8 +0,8 @@

import { AssistantAppState, AssistantServerAction, ClientLogger, VoicePlayerSettings, AssistantSettings, AssistantClientCustomizedCommand, AssistantSmartAppData } from './typings';
import { AssistantAppState, AssistantCharacterCommand, AssistantNavigationCommand, AssistantServerAction, AssistantSmartAppCommand, ClientLogger, VoicePlayerSettings, AssistantSettings } from './typings';
import { NativePanelParams } from './NativePanel/NativePanel';
export interface AssistantEvents<A extends AssistantSmartAppData> {
export interface AssistantEvents {
start: () => void;
data: (command: AssistantClientCustomizedCommand<A>) => void;
data: (command: AssistantCharacterCommand | AssistantNavigationCommand | AssistantSmartAppCommand) => void;
}
export declare const createAssistant: <A extends AssistantSmartAppData>({ getState, getRecoveryState, }: {
export declare const createAssistant: ({ getState, getRecoveryState, }: {
getState: () => AssistantAppState;

@@ -14,3 +14,3 @@ getRecoveryState?: (() => any) | undefined;

getRecoveryState: () => any;
on: <K extends "data" | "start">(event: K, cb: AssistantEvents<A>[K]) => () => void;
on: <K extends "data" | "start">(event: K, cb: AssistantEvents[K]) => () => void;
sendData: ({ action, name, requestId, }: {

@@ -25,3 +25,3 @@ action: AssistantServerAction;

};
export declare const createAssistantDev: <A extends AssistantSmartAppData>({ getState, getRecoveryState, initPhrase, nativePanel, url, userId, token, userChannel, surface, surfaceVersion, sdkVersion, enableRecord, recordParams, settings, voiceSettings, }: {
export declare const createAssistantDev: ({ getState, getRecoveryState, initPhrase, nativePanel, url, userId, token, userChannel, surface, surfaceVersion, sdkVersion, enableRecord, recordParams, settings, voiceSettings, }: {
getState: () => AssistantAppState;

@@ -49,3 +49,3 @@ getRecoveryState?: (() => Record<string, any> | undefined) | undefined;

getRecoveryState: () => any;
on: <K extends "data" | "start">(event: K, cb: AssistantEvents<A>[K]) => () => void;
on: <K extends "data" | "start">(event: K, cb: AssistantEvents[K]) => () => void;
sendData: ({ action, name, requestId, }: {

@@ -60,3 +60,3 @@ action: AssistantServerAction;

};
export declare const createSmartappDebugger: <A extends AssistantSmartAppData>({ token, initPhrase, getState, getRecoveryState, settings, }: {
export declare const createSmartappDebugger: ({ token, initPhrase, getState, getRecoveryState, settings, }: {
token: string;

@@ -71,3 +71,3 @@ initPhrase: string;

getRecoveryState: () => any;
on: <K extends "data" | "start">(event: K, cb: AssistantEvents<A>[K]) => () => void;
on: <K extends "data" | "start">(event: K, cb: AssistantEvents[K]) => () => void;
sendData: ({ action, name, requestId, }: {

@@ -74,0 +74,0 @@ action: AssistantServerAction;

@@ -0,13 +1,27 @@

var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import { createNanoEvents } from './nanoevents';
import { initializeAssistantSDK } from './dev';
export const createAssistant = ({ getState, getRecoveryState, }) => {
let currentGetState = getState;
let currentGetRecoveryState = getRecoveryState;
const { on, emit } = createNanoEvents();
export var createAssistant = function (_a) {
var getState = _a.getState, getRecoveryState = _a.getRecoveryState;
var currentGetState = getState;
var currentGetRecoveryState = getRecoveryState;
var _b = createNanoEvents(), on = _b.on, emit = _b.emit;
window.AssistantClient = {
onData: (command) => emit('data', command),
onRequestState: () => {
onData: function (command) {
return emit('data', command);
},
onRequestState: function () {
return currentGetState();
},
onRequestRecoveryState: () => {
onRequestRecoveryState: function () {
if (currentGetRecoveryState) {

@@ -18,54 +32,56 @@ return currentGetRecoveryState();

},
onStart: () => emit('start'),
onStart: function () { return emit('start'); },
};
setTimeout(() => { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.ready(); }); // таймаут для подписки на start
setTimeout(function () { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.ready(); }); // таймаут для подписки на start
return {
close: () => { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.close(); },
getInitialData: () => window.appInitialData,
getRecoveryState: () => window.appRecoveryState,
on,
sendData: ({ action, name, requestId, }) => {
var _a, _b, _c;
if ((_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.sendDataContainer) {
(_b = window.AssistantHost) === null || _b === void 0 ? void 0 : _b.sendDataContainer(
close: function () { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.close(); },
getInitialData: function () { return window.appInitialData; },
getRecoveryState: function () { return window.appRecoveryState; },
on: on,
sendData: function (_a) {
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) {
(_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 }));
JSON.stringify({ data: action, message_name: name || '', requestId: requestId }));
}
else {
(_c = window.AssistantHost) === null || _c === void 0 ? void 0 : _c.sendData(JSON.stringify(action), name || null);
(_d = window.AssistantHost) === null || _d === void 0 ? void 0 : _d.sendData(JSON.stringify(action), name || null);
}
},
setGetState: (nextGetState) => {
setGetState: function (nextGetState) {
currentGetState = nextGetState;
},
setGetRecoveryState: (nextGetRecoveryState) => {
setGetRecoveryState: function (nextGetRecoveryState) {
currentGetRecoveryState = nextGetRecoveryState;
},
setSuggest: (suggest) => { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.setSuggest(suggest); },
setSuggest: function (suggest) { var _a; return (_a = window.AssistantHost) === null || _a === void 0 ? void 0 : _a.setSuggest(suggest); },
};
};
export const createAssistantDev = ({ getState, getRecoveryState, initPhrase, nativePanel, url, userId, token, userChannel, surface, surfaceVersion, sdkVersion, enableRecord = false, recordParams, settings, voiceSettings, }) => {
export var createAssistantDev = function (_a) {
var getState = _a.getState, getRecoveryState = _a.getRecoveryState, initPhrase = _a.initPhrase, nativePanel = _a.nativePanel, url = _a.url, userId = _a.userId, token = _a.token, userChannel = _a.userChannel, surface = _a.surface, surfaceVersion = _a.surfaceVersion, sdkVersion = _a.sdkVersion, _b = _a.enableRecord, enableRecord = _b === void 0 ? false : _b, recordParams = _a.recordParams, settings = _a.settings, voiceSettings = _a.voiceSettings;
initializeAssistantSDK({
initPhrase,
nativePanel,
url,
userId,
token,
userChannel,
surface,
surfaceVersion,
sdkVersion,
enableRecord,
recordParams,
settings,
initPhrase: initPhrase,
nativePanel: nativePanel,
url: url,
userId: userId,
token: token,
userChannel: userChannel,
surface: surface,
surfaceVersion: surfaceVersion,
sdkVersion: sdkVersion,
enableRecord: enableRecord,
recordParams: recordParams,
settings: settings,
voiceSettings: voiceSettings || { startVoiceDelay: 1 },
});
return createAssistant({ getState, getRecoveryState });
return createAssistant({ getState: getState, getRecoveryState: getRecoveryState });
};
const parseJwt = (token) => {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64)
var parseJwt = function (token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(atob(base64)
.split('')
.map((c) => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)
.map(function (c) { return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); })
.join(''));

@@ -75,5 +91,6 @@ return JSON.parse(jsonPayload);

// Публичный метод, использующий токен из SmartApp Studio
export const createSmartappDebugger = ({ token, initPhrase, getState, getRecoveryState, settings = {}, }) => {
export var createSmartappDebugger = function (_a) {
var token = _a.token, initPhrase = _a.initPhrase, getState = _a.getState, getRecoveryState = _a.getRecoveryState, _b = _a.settings, settings = _b === void 0 ? {} : _b;
try {
const { exp } = parseJwt(token);
var exp = parseJwt(token).exp;
if (exp * 1000 <= Date.now()) {

@@ -92,7 +109,7 @@ alert('Срок действия токена истек!');

return createAssistantDev({
initPhrase,
token,
settings: Object.assign(Object.assign({}, settings), { authConnector: 'developer_portal_jwt' }),
getState,
getRecoveryState,
initPhrase: initPhrase,
token: token,
settings: __assign(__assign({}, settings), { authConnector: 'developer_portal_jwt' }),
getState: getState,
getRecoveryState: getRecoveryState,
url: 'wss://nlp2vps.online.sberbank.ru:443/vps/',

@@ -99,0 +116,0 @@ surface: 'SBERBOX',

@@ -1,19 +0,28 @@

export const createNanoEvents = () => {
let events = {};
const emit = (event, ...args) => {
for (const listener of events[event] || []) {
listener(...args);
export var createNanoEvents = function () {
var events = {};
var emit = function (event) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
for (var _a = 0, _b = events[event] || []; _a < _b.length; _a++) {
var listener = _b[_a];
listener.apply(void 0, args);
}
};
const on = (event, cb) => {
var on = function (event, cb) {
(events[event] = events[event] || []).push(cb);
return () => {
events[event] = events[event].filter((i) => i !== cb);
return function () {
events[event] = events[event].filter(function (i) { return i !== cb; });
};
};
const once = (event, cb) => {
var once = function (event, cb) {
// eslint-disable-next-line
// @ts-ignore И вот тут я сдался
const off = on(event, (...args) => {
cb(...args);
var off = on(event, function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
cb.apply(void 0, args);
off();

@@ -23,12 +32,12 @@ });

};
const clear = () => {
var clear = function () {
events = {};
};
return {
events,
emit,
on,
once,
clear,
events: events,
emit: emit,
on: on,
once: once,
clear: clear,
};
};
import React from 'react';
import { SuggestionButtonType } from '../typings';
import './styles.css';
export interface NativePanelParams {

@@ -5,0 +4,0 @@ defaultText: string;

@@ -0,11 +1,22 @@

var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
/* stylelint-disable */
import React, { useState, useEffect, useCallback } from 'react';
import { render } from 'react-dom';
import assistantSphereIcon from './sphere.png';
import './styles.css';
export const NativePanel = ({ defaultText, sendText, className, tabIndex, suggestions, bubbleText, onListen, onSubscribeListenStatus, onSubscribeHypotesis, }) => {
const [value, setValue] = useState(defaultText);
const [recording, setRecording] = useState(false);
const [bubble, setBubble] = useState(bubbleText);
const [prevBubbleText, setPrevBubbleText] = useState(bubbleText);
var assistantSphereIcon = 'data:image/png;base64,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';
export var NativePanel = function (_a) {
var defaultText = _a.defaultText, sendText = _a.sendText, className = _a.className, tabIndex = _a.tabIndex, suggestions = _a.suggestions, bubbleText = _a.bubbleText, onListen = _a.onListen, onSubscribeListenStatus = _a.onSubscribeListenStatus, onSubscribeHypotesis = _a.onSubscribeHypotesis;
var _b = useState(defaultText), value = _b[0], setValue = _b[1];
var _c = useState(false), recording = _c[0], setRecording = _c[1];
var _d = useState(bubbleText), bubble = _d[0], setBubble = _d[1];
var _e = useState(bubbleText), prevBubbleText = _e[0], setPrevBubbleText = _e[1];
if (bubbleText !== prevBubbleText) {

@@ -15,20 +26,20 @@ setPrevBubbleText(bubbleText);

}
const handleSphereClick = useCallback(() => {
var handleSphereClick = useCallback(function () {
setValue('');
onListen();
}, [onListen]);
const createSuggestClickHandler = (suggest) => () => {
const { action } = suggest;
var createSuggestClickHandler = function (suggest) { return function () {
var action = suggest.action;
if ('text' in action) {
sendText(action.text);
}
};
useEffect(() => {
const unsubscribeStatus = onSubscribeListenStatus((type) => {
}; };
useEffect(function () {
var unsubscribeStatus = onSubscribeListenStatus(function (type) {
setRecording(type === 'listen');
});
const unsubscribeHypotesis = onSubscribeHypotesis((hypotesis, last) => {
var unsubscribeHypotesis = onSubscribeHypotesis(function (hypotesis, last) {
setValue(last ? '' : hypotesis);
});
return () => {
return function () {
unsubscribeStatus();

@@ -38,11 +49,11 @@ unsubscribeHypotesis();

}, [onSubscribeListenStatus, onSubscribeHypotesis]);
return (React.createElement("div", { className: className ? `nativePanel ${className}` : 'nativePanel' },
bubble && (React.createElement("div", { className: "bubble", onClick: () => setBubble('') }, bubble)),
return (React.createElement("div", { className: className ? "nativePanel " + className : 'nativePanel' },
bubble && (React.createElement("div", { className: "bubble", onClick: function () { return setBubble(''); } }, bubble)),
React.createElement("div", { className: recording ? 'sphere active' : 'sphere', onClick: handleSphereClick, style: {
backgroundImage: `url(${assistantSphereIcon})`,
backgroundImage: "url(" + assistantSphereIcon + ")",
} }),
React.createElement("label", { htmlFor: "voice", className: "label" }, "\u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435"),
React.createElement("input", { id: "voice", value: value, onChange: (e) => {
React.createElement("input", { id: "voice", value: value, onChange: function (e) {
setValue(e.currentTarget.value);
}, tabIndex: typeof tabIndex === 'number' && Number.isInteger(tabIndex) ? tabIndex : -1, disabled: recording, onKeyDown: (e) => {
}, tabIndex: typeof tabIndex === 'number' && Number.isInteger(tabIndex) ? tabIndex : -1, disabled: recording, onKeyDown: function (e) {
if (e.key === 'Enter') {

@@ -53,6 +64,6 @@ sendText(value);

}, className: "input" }),
React.createElement("div", { className: "suggestPanel" }, suggestions.map((s) => (React.createElement("div", { key: `suggest-${s.title}`, onClick: createSuggestClickHandler(s), className: "suggest" }, s.title))))));
React.createElement("div", { className: "suggestPanel" }, suggestions.map(function (s) { return (React.createElement("div", { key: "suggest-" + s.title, onClick: createSuggestClickHandler(s), className: "suggest" }, s.title)); }))));
};
let div;
export const renderNativePanel = (props) => {
var div;
export var renderNativePanel = function (props) {
if (!div) {

@@ -62,3 +73,8 @@ div = document.createElement('div');

}
render(React.createElement(NativePanel, Object.assign({}, props)), div);
render(React.createElement(NativePanel, __assign({}, props)), div);
};
// стили
var NativePanelStyles = "\n@keyframes rotation {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.nativePanel {\n background-color: rgba(255, 255, 255, 0.04);\n backdrop-filter: blur(5px);\n box-sizing: border-box;\n display: flex;\n align-items: center;\n position: fixed;\n z-index: 999;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 144px;\n padding: 36px 128px;\n border-top-left-radius: 24px;\n border-top-right-radius: 24px;\n}\n\n.bubble {\n cursor: pointer;\n position: absolute;\n bottom: calc(100% - 36px);\n max-width: 500px;\n border-radius: 24px 24px 24px 6px;\n background-color: rgba(255, 255, 255, 0.08);\n padding: 12px 24px;\n font-size: 24px;\n line-height: 24px;\n font-weight: 500;\n color: #fff;\n z-index: -1;\n}\n\n.sphere {\n background-size: contain;\n width: 72px;\n height: 72px;\n\n transition: transform 0.2s;\n\n}\n\n.sphere:hover {\n transform: scale(1.1);\n}\n\n.sphere.active {\n animation: rotation 2s linear infinite;\n}\n\n.input {\n font-size: 36px;\n line-height: 42px;\n font-weight: 500;\n color: #fff;\n height: 42px;\n padding: 0;\n margin: 0;\n outline: none;\n border: 0;\n background: transparent;\n}\n\n.label {\n font-size: 36px;\n line-height: 42px;\n font-weight: 500;\n color: #fff;\n opacity: 0.5;\n padding-left: 40px;\n padding-right: 10px;\n}\n\n.suggestPanel {\n position: absolute;\n top: 15px;\n right: 25px;\n display: flex;\n flex-direction: row;\n height: 28px;\n}\n\n.suggest {\n line-height: 26px;\n padding: 0 15px;\n margin-left: 5px;\n border: 1px solid #c4c4c4;\n border-radius: 16px;\n color: #fff;\n cursor: pointer;\n font-size: 14px;\n}\n";
var style = document.createElement('style');
style.appendChild(document.createTextNode(NativePanelStyles));
document.getElementsByTagName('head')[0].appendChild(style);

@@ -1,11 +0,11 @@

export const createCallbackLogger = (cb) => ({
logInit: (message) => {
export var createCallbackLogger = function (cb) { return ({
logInit: function (message) {
cb({ type: 'params', parameters: message });
},
logIncoming: (message) => {
cb({ type: 'incoming', message });
logIncoming: function (message) {
cb({ type: 'incoming', message: message });
},
logOutcoming: (message) => {
cb({ type: 'outcoming', message });
logOutcoming: function (message) {
cb({ type: 'outcoming', message: message });
},
});
}); };

@@ -1,7 +0,8 @@

const CURRENT_VERSION = '0.1.0';
const getDefaultLog = () => ({ entries: [], version: CURRENT_VERSION });
export const createLogCallbackRecorder = (subscribe, defaultActive = true) => {
let isActive = defaultActive;
let currentLog = getDefaultLog();
subscribe((entry) => {
var CURRENT_VERSION = '0.1.0';
var getDefaultLog = function () { return ({ entries: [], version: CURRENT_VERSION }); };
export var createLogCallbackRecorder = function (subscribe, defaultActive) {
if (defaultActive === void 0) { defaultActive = true; }
var isActive = defaultActive;
var currentLog = getDefaultLog();
subscribe(function (entry) {
var _a, _b;

@@ -45,15 +46,15 @@ if (isActive === false) {

});
const getRecord = () => currentLog;
const start = () => {
var getRecord = function () { return currentLog; };
var start = function () {
currentLog = getDefaultLog();
isActive = true;
};
const stop = () => {
var stop = function () {
isActive = false;
};
return {
getRecord,
start,
stop,
getRecord: getRecord,
start: start,
stop: stop,
};
};

@@ -1,11 +0,14 @@

export const createConsoleLogger = (level = 'debug') => ({
logInit: (message) => {
console[level]('Initialize', message);
},
logIncoming: (message) => {
console[level]('Received message', message);
},
logOutcoming: (message) => {
console[level]('Sended message', message);
},
});
export var createConsoleLogger = function (level) {
if (level === void 0) { level = 'debug'; }
return ({
logInit: function (message) {
console[level]('Initialize', message);
},
logIncoming: function (message) {
console[level]('Received message', message);
},
logOutcoming: function (message) {
console[level]('Sended message', message);
},
});
};
import { LogRecorder, RecordSaver } from '../typings';
import './styles.css';
export declare const renderAssistantRecordPanel: (recorder: LogRecorder, saver: RecordSaver) => void;
//# sourceMappingURL=index.d.ts.map
import React, { useEffect, useRef, useState } from 'react';
import { render } from 'react-dom';
import './styles.css';
const AssistantRecordPanel = ({ recorder, onSave }) => {
const [isRecording, setIsRecording] = useState(true);
const [record, setRecord] = useState();
const recorderRef = useRef();
const handleStart = React.useCallback(() => {
var AssistantRecordPanel = function (_a) {
var recorder = _a.recorder, onSave = _a.onSave;
var _b = useState(true), isRecording = _b[0], setIsRecording = _b[1];
var _c = useState(), record = _c[0], setRecord = _c[1];
var recorderRef = useRef();
var handleStart = React.useCallback(function () {
var _a;

@@ -14,3 +14,3 @@ (_a = recorderRef.current) === null || _a === void 0 ? void 0 : _a.start();

}, []);
const handleStop = React.useCallback(() => {
var handleStop = React.useCallback(function () {
var _a, _b;

@@ -21,3 +21,3 @@ (_a = recorderRef.current) === null || _a === void 0 ? void 0 : _a.stop();

}, []);
const handleSave = React.useCallback(() => {
var handleSave = React.useCallback(function () {
if (record) {

@@ -27,3 +27,3 @@ onSave(record);

}, [onSave, record]);
useEffect(() => {
useEffect(function () {
var _a;

@@ -38,6 +38,10 @@ (_a = recorderRef.current) === null || _a === void 0 ? void 0 : _a.stop();

};
export const renderAssistantRecordPanel = (recorder, saver) => {
const div = document.createElement('div');
export var renderAssistantRecordPanel = function (recorder, saver) {
var div = document.createElement('div');
document.body.appendChild(div);
render(React.createElement(AssistantRecordPanel, { recorder: recorder, onSave: saver.save }), div);
};
var RecordPanelStyles = "\n.recordPanel {\n position: fixed;\n z-index: 999;\n top: 0;\n right: 0;\n}\n\n.recordButton {\n margin-right: 8px;\n margin-top: 8px;\n}\n";
var style = document.createElement('style');
style.appendChild(document.createTextNode(RecordPanelStyles));
document.getElementsByTagName('head')[0].appendChild(style);

@@ -1,8 +0,10 @@

const CURRENT_VERSION = '0.1.0';
export const createRecordOfflinePlayer = (record, context = window) => {
let currentRecord = record;
let entryCursor = 0;
const playMessage = (message) => {
var CURRENT_VERSION = '0.1.0';
export var createRecordOfflinePlayer = function (record, context) {
if (context === void 0) { context = window; }
var currentRecord = record;
var entryCursor = 0;
var playMessage = function (message) {
var _a;
for (const item of message.items) {
for (var _i = 0, _b = message.items; _i < _b.length; _i++) {
var item = _b[_i];
if (item.command) {

@@ -13,7 +15,7 @@ ((_a = context.AssistantClient) === null || _a === void 0 ? void 0 : _a.onData) && context.AssistantClient.onData(item.command);

};
const playNext = () => {
var playNext = function () {
if (!currentRecord || entryCursor + 1 >= currentRecord.entries.length) {
return false;
}
let entry = currentRecord.entries[entryCursor++];
var entry = currentRecord.entries[entryCursor++];
while ((entry.type !== 'incoming' || entry.message == null) && entryCursor < currentRecord.entries.length) {

@@ -25,5 +27,5 @@ entry = currentRecord.entries[entryCursor++];

}
return currentRecord.entries.some((e, i) => { var _a; return i > entryCursor && e.type === 'incoming' && ((_a = e.message) === null || _a === void 0 ? void 0 : _a.data) != null; });
return currentRecord.entries.some(function (e, i) { var _a; return i > entryCursor && e.type === 'incoming' && ((_a = e.message) === null || _a === void 0 ? void 0 : _a.data) != null; });
};
const play = () => {
var play = function () {
var _a;

@@ -34,3 +36,3 @@ ((_a = context.AssistantClient) === null || _a === void 0 ? void 0 : _a.onStart) && context.AssistantClient.onStart();

}
let end = false;
var end = false;
while (!end) {

@@ -40,3 +42,3 @@ end = !playNext();

};
const setRecord = (rec) => {
var setRecord = function (rec) {
if (rec.version !== CURRENT_VERSION) {

@@ -50,5 +52,5 @@ throw new Error('Unsupported log version');

continue: playNext,
play,
setRecord,
play: play,
setRecord: setRecord,
};
};

@@ -1,6 +0,6 @@

export const createRecordDownloader = () => {
export var createRecordDownloader = function () {
return {
save: (record) => {
const dataStr = `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(record))}`;
const anchor = document.createElement('a');
save: function (record) {
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(record));
var anchor = document.createElement('a');
anchor.setAttribute('href', dataStr);

@@ -7,0 +7,0 @@ anchor.setAttribute('download', 'assistant-log.json');

@@ -92,2 +92,6 @@ /// <reference types="long" />

export declare type AssistantCharacterType = 'sber' | 'eva' | 'joy';
export interface SdkMeta {
mid?: number;
requestId?: string;
}
export interface AssistantCharacterCommand {

@@ -98,6 +102,2 @@ type: 'character';

};
sdkMeta?: {
mid?: number;
requestId?: string;
};
}

@@ -112,15 +112,6 @@ export interface AssistantCloseAppCommand {

};
sdkMeta?: {
mid?: number;
requestId?: string;
};
sdkMeta?: SdkMeta;
}
export interface AssistantSmartAppData {
export interface AssistantSmartAppCommand {
type: 'smart_app_data';
sdkMeta?: {
mid?: number;
requestId?: string;
};
}
export interface AssistantSmartAppCommand extends AssistantSmartAppData {
smart_app_data: {

@@ -130,2 +121,3 @@ command: string;

};
sdkMeta?: SdkMeta;
}

@@ -145,4 +137,2 @@ export interface AssistantPlayerCommand {

}
export declare type AssistantClientCustomizedCommand<T> = AssistantCharacterCommand | AssistantNavigationCommand | T;
export declare type AssistantClientCommand = AssistantClientCustomizedCommand<AssistantSmartAppCommand>;
export interface AssistantClient {

@@ -152,3 +142,3 @@ onStart?: () => void;

onRequestRecoveryState?: () => any;
onData?: (command: AssistantClientCommand) => void;
onData?: (command: AssistantCharacterCommand | AssistantNavigationCommand | AssistantSmartAppCommand) => void;
}

@@ -155,0 +145,0 @@ export interface AssistantHost {

{
"name": "@sberdevices/assistant-client",
"version": "2.1.0-canary.58.03ac302471e41b44fd8a93a6dac19b85a3693042.0",
"version": "2.1.0",
"description": "Модуль взаимодействия с виртуальным ассистентом",
"main": "dist/index.js",
"unpkg": "umd/assistant.min.js",
"jsnext:main": "umd/assistant.esm.js",
"scripts": {
"build": "rm -rf dist tsconfig.tsbuildinfo && rollup -c && tsc -m ES2015 --outDir dist",
"prepublishOnly": "npm run build",
"release": "auto shipit",
"prepublishOnly": "rm -rf dist tsconfig.tsbuildinfo && tsc && rsync -rlptgoD --include=\"*/\" --include '*.png' --include '*.css' --exclude '*' src/ dist/",
"proto": "pbjs -t static-module src/proto.proto > src/proto.js && pbts src/proto.js -o src/proto.d.ts",

@@ -44,2 +47,5 @@ "asr": "pbjs -t static-module src/asr/index.proto > src/asr/index.js && pbts src/asr/index.js -o src/asr/index.d.ts",

"@cypress/webpack-preprocessor": "5.4.5",
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-typescript": "^6.1.0",
"@types/jest": "26.0.14",

@@ -73,3 +79,6 @@ "@types/mocha": "8.0.3",

"react-scripts": "3.4.3",
"rollup": "^2.33.2",
"rollup-plugin-terser": "^7.0.2",
"ts-loader": "8.0.4",
"tslib": "^2.0.3",
"typescript": "3.9.2",

@@ -83,3 +92,4 @@ "webpack": "4.44.2"

"files": [
"dist"
"dist",
"umd"
],

@@ -86,0 +96,0 @@ "auto": {

@@ -51,3 +51,12 @@ [![npm ui](https://img.shields.io/npm/v/@sberdevices/assistant-client)](https://www.npmjs.com/package/@sberdevices/assistant-client)

#### Альтернативное подключение
Assitant-client доступен для подключения через `<script>`. В этом случае, подключение react обязательно. Версии react и assistant-client можно поменять в src.
```html
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@sberdevices/assistant-client@2.1.0/umd/assistant.min.js"></script>
```
### Пример использования

@@ -54,0 +63,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet